Правильный способ для Fire-and-Forget асинхронного делегата
Считайте меня ржавым по поводу асинхронных делегатов.
Если я хочу вызвать метод асинхронно, в стиле "огонь и забуй", это подходящий способ сделать это?
Action action = DoSomething;
action.BeginInvoke(action.EndInvoke, null);
Метод DoSomething()
обнаруживает все исключения и обрабатывает их внутри.
Соответствует ли вызов EndInvoke
? Необходимые?
Есть ли более четкий способ достичь такого же поведения?
Ответы
Ответ 1
"Старая школа" в .NET 3.5 заключается в использовании ThreadPool
:
ThreadPool.QueueUserWorkItem(s => DoSomething());
Если вы предпочитаете использовать асинхронные делегаты, тогда вы должны знать, что требуется вызов EndInvoke
, даже если у вас нет дополнительного кода, который вы хотите выполнить при обратном вызове.
Ответ 2
Новый способ (в .NET 4) заключается в следующем:
Task.Factory.StartNew(() => DoSomething());
Ответ 3
Следует отметить, что
Task.Factory.StartNew(() => DoSomething());
не видит никакого потенциального исключения, вызванного методом DoSomething. Я знаю, что это именно то, что нужно при запуске операции "огонь-и-забыть", но, насколько это касается .Net 4, любая задача с незаметным исключением, завершаемая сборщиком мусора, будет эскалацией как необработанное исключение, которое убьет ваш процесс, Однако в .Net 4.5 поведение по умолчанию изменилось (см. Ключевые слова async и ожидания).