Есть ли способ, которым я могу встроить делегированную задачу, а не разделять ее на другую функцию?
Оригинальный код:
private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{
System.Threading.ThreadPool.QueueUserWorkItem((o) => Attach());
}
void Attach() // I want to inline this function on FileOk event
{
if (this.InvokeRequired)
{
this.Invoke(new Action(Attach));
}
else
{
// attaching routine here
}
}
Я хотел, чтобы это было так (нет необходимости создавать отдельную функцию):
private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{
Action attach = delegate
{
if (this.InvokeRequired)
{
// but it has compilation here
// "Use of unassigned local variable 'attach'"
this.Invoke(new Action(attach));
}
else
{
// attaching routine here
}
};
System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
}
Я думаю, что это сработает:
private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{
Action attach = null;
attach = delegate
{
if (this.InvokeRequired)
{
// since we assigned null, we'll be ok, and the automatic
// closure generated by the compiler will make sure the value is here when
// we need it.
this.Invoke(new Action(attach));
}
else
{
// attaching routine here
}
};
System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
}
Все, что вам нужно сделать, это присвоить значение "attach" (null works) перед строкой, объявляющей анонимный метод. Я думаю, что первое немного легче понять.
Причина, по которой вы получаете ошибку "использование непризнанной переменной", объясняется тем, как компилятор действительно генерирует код. Когда вы используете синтаксис delegate {}, реальный метод создается для вас компилятором. Поскольку вы ссылаетесь на прикрепленное поле в своем делете, компилятор пытается передать локальную переменную attach
в сгенерированный метод делегата.
Здесь грубо переведенный код, который должен помочь сделать его более ясным:
private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{
Action attach = _b<>_1( attach );
System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
}
private Action _b<>_1( Action attach )
{
if (this.InvokeRequired)
{
// but it has compilation here
// "Use of unassigned local variable 'attach'"
this.Invoke(new Action(attach));
}
else
{
// attaching routine here
}
}
Обратите внимание, что перед передачей этого поля передается поле attach в метод _b < > _.