Тут решил в одном проекте таки заюзать это чудо, вещь, конечно, забавная, но мозг выворачивает наизнанку. Обычное асинхронное программирование после этого кажется абсолютно простым и очевидным.
В качестве выворота мозга приведу простой пример (он упрощён до предела, в реальности, конечно, всё было сложнее):
Итак, есть метод Process, который ловит все исключения и обрабатывает их, и метод DoSomething, который в процессе своей работы может кинуть эксепшен.
Как думаете, что будет в результате выполнения данного кода (вызова метода Process)?
Подумали? Теперь правильный ответ. Будет необработанный эксепшен и аварийное завершение приложения. Бздынь! Размещаем метод DoSomething где-нибудь подальше и наслаждаемся неожиданными крешами приложения в самый неожиданный момент.
Вот это один из примеров разрыва шаблонов. Чтобы такого не повторилось DoSomething должен возвращать не void а человеческий Task, после этого, чтобы избавиться от предупреждения о некорректном поведении в методе Process надо написать await DoSomething, а чтобы скомпилировалось к Process добавить async. И вот только после этого всё будет работать как и ожидалось.
Приятного кодинга
В качестве выворота мозга приведу простой пример (он упрощён до предела, в реальности, конечно, всё было сложнее):
public static void Process()
{
try
{
DoSomething();
}
catch (Exception)
{
}
}
public static async void DoSomething()
{
throw new Exception();
}
{
try
{
DoSomething();
}
catch (Exception)
{
}
}
public static async void DoSomething()
{
throw new Exception();
}
Итак, есть метод Process, который ловит все исключения и обрабатывает их, и метод DoSomething, который в процессе своей работы может кинуть эксепшен.
Как думаете, что будет в результате выполнения данного кода (вызова метода Process)?
Подумали? Теперь правильный ответ. Будет необработанный эксепшен и аварийное завершение приложения. Бздынь! Размещаем метод DoSomething где-нибудь подальше и наслаждаемся неожиданными крешами приложения в самый неожиданный момент.
Вот это один из примеров разрыва шаблонов. Чтобы такого не повторилось DoSomething должен возвращать не void а человеческий Task, после этого, чтобы избавиться от предупреждения о некорректном поведении в методе Process надо написать await DoSomething, а чтобы скомпилировалось к Process добавить async. И вот только после этого всё будет работать как и ожидалось.
Приятного кодинга
Не понятно к чемуЭто ты решил написать про такой пример. Ну да, такое возможно. Значит ли, что такой код стоит писать? Конечно нет. http://msdn.microsoft.com/en-us/library/hh524395.aspx#BKMK_VoidReturnType то
ОтветитьУдалитьК тому, что поведение слишком неочевидное и нелогичное, хоть и описано в документации. Fire and forget и невозможность перехватить эксепшены вообще не вяжется. С тасками уже подобное делали, и переделали, когда до использования дошло http://force-net.com/2013/06/task.html
ОтветитьУдалитьНа сколько я помню - этот код выдаст тебе compilation warning :) Не логично будет игнорировать warnings. async и await - это просто кодогенерация. Никакого волшебства. Так к этому и стоит относиться.
ОтветитьУдалитьЭто очень хитрая кодогенерация, которая по факту меняет весь твой код. И её надо бы хорошо понимать, чтобы не нарваться на проблему. Варнинг тут, кстати, только на лишний async в DoSomething, но это из-за слишком упрощённого примера.
ОтветитьУдалить