#c# #winforms #asynchronous #lambda
#c# #winforms #асинхронный #лямбда
Вопрос:
Я пытаюсь создать метод, который асинхронно присваивается в программе Winforms с использованием BackgroundWorker
.
void Assign<T>(Func<object> method, ref T obj)
{
var bw = new BackgroundWorker();
bw.DoWork =
(object sender, DoWorkEventArgs e) =>
e.Result = ((Func<object>)(e.Argument))();
bw.RunWorkerCompleted =
(object sender, RunWorkerCompletedEventArgs e) =>
obj = (T)e.Resu< // Error here
bw.RunWorkerAsync(method);
}
Assign(slowMethodReturnsFloat, ref aFloatVariable);
Assign(slowMethodReturnsDataSet, ref aDataSetVar);
Однако я получил ошибку:
«Невозможно использовать параметр ref или out внутри лямбда-выражения»
Есть ли другой способ его реализации? Какой-либо подход не используется BackgroundWorker
?
Комментарии:
1. Почему бы вам просто не вернуться
T
? (неважно, вы пытаетесь сохранить рабочий процесс с помощью BGworker, а не сделать асинхронным).2. Это
bw.DoWork = (object sender, DoWorkEventArgs e) => ...
прямой путь к утечке памяти3. @T.S. Можете ли вы дать некоторые подробности об
DoWork
утечке памяти и?4. Вы подписываетесь на событие и не отказываетесь от подписки. Это одна из тех вещей, которые часто забывают программисты. Вы должны сделать
var handler = (object sender, DoWorkEventArgs e) => ...; bw.DoWork = handler;
, а затемbw.DoWork -= handler;
увидеть ловушку # 5 visualstudiomagazine.com/articles/2010/08/31 /…5. @T.S. Спасибо. Какое лучшее место для отмены подписки
DoWork
иRunWorkCompleted
? Внутренняя часть кода подписанаRunWorkCompleted
? Или закрыть форму? Интересно, что пример статьи MSDN даже не отменяет подписку на события msdn.microsoft.com/en-us/library/cc221403 (v= против 95).aspx .
Ответ №1:
Рассмотрите возможность передачи лямбда-выражения вместо в ref
качестве второго аргумента:
void Assign<T>(Func<object> method, Action<T> objSetter)
{
var bw = new BackgroundWorker();
bw.DoWork =
(object sender, DoWorkEventArgs e) =>
e.Result = ((Func<object>)(e.Argument))();
bw.RunWorkerCompleted =
(object sender, RunWorkerCompletedEventArgs e) =>
objSetter((T)e.Result);
bw.RunWorkerAsync(method);
}
Assign(slowMethodReturnsFloat, ret => aFloatVariable = ret);
Assign(slowMethodReturnsDataSet, ret => aDataSetVar = ret);
Ответ №2:
Я не уверен, что T
это такое, но другим вариантом может быть передача обратного вызова:
void Assign<T>(Func<object> method, Action<T> callBack);
void callBack(T result)