21
async/await: собираем грабли Андрей Часовских Broadridge Financial Solu>ons .NEXT 2014 Moscow

async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

async/await:  собираем  грабли Андрей  Часовских  

Broadridge  Financial  Solu>ons  

       

.NEXT  2014  Moscow  

Page 2: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронное  программирование

• Управление  получаем  сразу  после  вызова  операции  • Об  окончании  операции  нас  уведомляет  коллбэк  • Преимущества  

•  Отзывчивость  •  Масштабируемость  

2  

Page 3: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронное  программирование  в  .NET

• Asynchronous  Programming  Model  (BeginXxx/EndXxx)  •  Event-­‐based  Asynchronous  Programming  (XxxAsync(),  XxxCompleted)  •  Task-­‐based  Asynchronous  Programming  (async/await,  Task/Task<T>)  

•  Ссылка  на  документ  в  конце  презентации  

3  

Page 4: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

4  

Page 5: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронность  !=  многопоточность

5  

Page 6: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Синхронный  ввод-­‐вывод

var  stream  =  new  FileStream(…);  int  bytes  =  stream.Read(…);  

WinAPI  ReadFile(…)  

Диспетчер  ввода-­‐вывода  Блокирует  

поток  Очередь  пакетов  

6  

Page 7: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Сервер  в  вакууме  

Синхронный  ввод-­‐вывод:  пример

Жесткий  диск  

7  

Page 8: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронный  ввод-­‐вывод

var  stream  =  new  FileStream(…,  FileOp>ons.Asynchronous);  int  bytes  =  await  stream.ReadAsync(…);  

WinAPI  ReadFile(…)  

Диспетчер  ввода-­‐вывода  

Возвращает  управление  

Очередь  пакетов  

8  

Overlapped  

Page 9: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронный  ввод-­‐вывод:  пример

9  

Сервер  в  вакууме  

Жесткий  диск  

Page 10: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

• Ключевое  слово  async  •  Разрешает  использовать  await  •  «Передает»  результат  метода  или  исключение  вверх  по  стеку  •  Для  такого  метода  компилятор  генерирует  стейт-­‐машину  

• Ключевое  слово  await  •  Вставляет  точку  возможного  прерывания/возобновления  метода  •  Извлекает  результат  или  исключение  из  таска  

async/await

10  

Page 11: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Реализация async  Task  FooAsync()  {          M1();          await  BarAsync();          M2();  }    //  примерный  сгенерированный  код  Task  FooAsync()  {          var  sm  =  new  FooAsyncStruct();          sm.this  =  this;          sm.builder  =  AsyncTaskMethodBuilder.Create();          sm.state  =  -­‐1;          …          sm.MoveNext();          return  sm.builder.Task;  }     11  

struct  FooAsyncStruct  :  IAsyncStateMachine  {          public  AsyncTaskMethodBuilder  builder;          public  SomeType  this;          public  int  state;          …                    private  void  MoveNext()  {                  try  {              switch  (state)  {                                  …                            }                  }                  catch  (Exception  ex)  {                          builder.SetException(ex);                          return;                  }                  builder.SetResult();          }  }  

Page 12: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

12  

async  Task  FooAsync()  {          M1();          await  BarAsync();          M2();  }  

//  примерный  код  того,  что  происходит  внутри  каждого  состояния  M1();    var  task  =  BarAsync();  var  awaiter  =  task.GetAwaiter();    Action  postback  =  ()  =>  {            awaiter.GetResult();          M2();  }    if  (awaiter.IsCompleted)  {          postback();  }  else  {            var  context  =  SynchronizationContext.Current;            if  (context  ==  null)  {                  context  =  new  SynchronizationContext();          }          var  contextCopy  =  context.CreateCopy();          awaiter.OnCompleted(()  =>  contextCopy.Post(postback,  null));    }  

Контекст    пула  потоков  

Захват  контекста  Синхронное  выполнение  

Page 13: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Заблуждения

•  async  методы  выполняются  в  другом  потоке  • С  помощью  await  метод  выполняется  в  другом  потоке  

•  await  вообще  не  запускает  методы  • Продолжение  метода  выполняется  в  другом  потоке  

•  Не  всегда:  ожидаемый  объект  уже  завершен  или  однопоточный  контекст  не  был  захвачен    

13  

Page 14: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

«async/await  позволяет  использовать  модель  синхронного  программирования  для  написания  кода,  выполняющего  операции  

ввода-­‐вывода  без  блокировки  потоков.  И  т.о.  создавать  более  отзывчивое  и  масштабируемое  

программное  обеспечение.»    

Джеффри  Рихтер  

14  

Page 15: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

async  void

• Исключения  выбрасываются  в  вызывающий  контекст  •  Могут  завершить  процесс  

• Не  узнаем  об  окончании  операции  •  Только  для  обработчиков  событий  и  подобных  штук  

15  

Page 16: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Асинхронные  лямбды

• Это  Ac>on  или  Func<Task>?  • Ac>on  ==  async  void  • Проверять  тип  делегата!    Task  t  =  null;  SomeMethod(()  =>  t  =  FooAsync());  await  t;  

 

16  

Page 17: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Таск,  которого  не  ждут

• Не  узнаем  об  исключениях  или  узнаем  слишком  поздно  •  Могут  завершить  процесс  •  TaskScheduler.UnobservedTaskExcep>on  

• Не  узнаем  об  окончании  операции  

17  

Page 18: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Блокировка  таска

• Блокируем  текущий  поток  • Возможен  дедлок  

18  

Page 19: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Используйте  Task.ConfigureAwait(false)

• Не  захватываем  текущий  контекст  •  Минимизируем  переключения  между  потоками  

• Для  библиотечных  вызовов  •  Захват  контекста  –  для  вызовов  верхнего  уровня  

19  

Page 20: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Async  all  the  way

• Нежелательно  смешивать  синхронный  и  асинхронный  код  •  async/await  стремится  распространяться  по  коду  • Избавляемся  от  простых  ошибок  

20  

Page 21: async/await:собираемграбли - JUG Ru Grouppublic.jugru.org/dotnext/2014/moscow/chasovskikh.pdf• Ключевое’слово’async’ • Разрешает’использовать’await

Спасибо!

• Pfx  Team  h�p://blogs.msdn.com/b/pfxteam/  •  Stephen  Cleary  h�p://blog.stephencleary.com/  •  Lucian  Wischik  h�p://blogs.msdn.com/lucian  •  TAP  h�p://aka.ms/tap      h�p://andreycha.info  h�p://github.com/andreycha/DotNext2014Moscow  

21