190 likes | 374 Views
Asynchrony in (ASP).NET. Aliaksandr Famin ShurickFomin@gmail.com @ AlexSane. Developer and a Kettle. Developer and a Kettle. Wait Make someone to wait Check periodically Make someone to check Put a whistle on a kettle Add a web-interface to a kettle. Sync Sync with threads Async-sync
E N D
Asynchrony in (ASP).NET Aliaksandr FaminShurickFomin@gmail.com @AlexSane
Developer and a Kettle • Wait • Make someone to wait • Check periodically • Make someone to check • Put a whistle on a kettle • Add a web-interface to a kettle • Sync • Sync with threads • Async-sync • Async with threads • Async with callbacks • Async with events
Evolution: WinAPI • struct OVERLAPPED (IAsyncResult) • OVERLAPPED_COMPLETION_ROUTINE (AsyncCallback)
Evolution: .NET 1.0 – 1.1 • IAsyncResult • AsyncCallback • BeginXXX(@params, callback, userState) • EndXXX(asyncResult)
Evolution: .NET 2.0 – … • event XXXCompleted • XXXCompletedEventArgs • EventHandler<XXXCompletedEventArgs> • XXXAsync(@params, userState) • CancelAsync() • AsyncOperationManager • AsyncOperation • SyncronizationContext
Evolution: .NET 4.0 • Task Parallel Library
IAsyncResult vs Events IAsyncResult Events Event handlers are underlock HttpContextavailable Chaining is simple Component-oriented • Callbacks are not thread safe • No context in callbacks (i.e. no HttpContext) • Complexity of chaining (custom IAsyncResult, etc.) • Poor support of components ContextAwareResult, but no guarantee
Event-based async pattern X Y Z AsyncOperationManager SyncronizationContext All operations arecompleted Thread #1 XAsync YAsync PreRenderComplete PreRender ZAsync XCompleted Thread #2 Thread #3 YCompleted ZCompleted Thread #4
TTT #1: Use closures var asyncResult = component.BeginSomeOperation(parameter, aresult => TrickyCallback(aresult, component), state); void TrickyCallback(IAsyncResult state, Component component) { bool result = component.EndOperation(state); }
TTT#2: Use userState carefully staticvoid Main(string[] args) { varasyncResult = component.BeginSomeOperation( parameter, Callback, state); } void Callback(IAsyncResultaresult) { bool result = component.EndOperation(aresult); objectstate = asyncResult.AsyncState; }
TTT#3: Unsubscribe from events staticvoid Main(string[] args) { component.OperationCompleted += component_OperationCompleted; component.OperationAsync("data", null); } staticvoidcomponent_OperationCompleted(object sender, EventArgs e) { component.OperationCompleted -= component_OperationCompleted; }
TTT#6 AsyncResult callbacks don’t have HttpContext • It could be, but there is no guarantee
TTT#7 Do not convert event-based pattern to IAsyncResult one • Event-based pattern uses locks, that could be not desirable
TTT #8: Do not use [ThreadStatic] • Do not forget about ThreadPool
TTT#9: Do not throw exceptions in callbacks • Even WSE 3.0 has had a bug we had spotted.