Asynchrony in (ASP).NET Aliaksandr

Preview:

DESCRIPTION

1.Wait 2.Make someone to wait 3.Check periodically 4.Make someone to check 5.Put a whistle on a kettle 6.Add a web-interface to a kettle 1.Sync 2.Sync with threads 3.Async-sync 4.Async with threads 5.Async with callbacks 6.Async with events

Citation preview

Asynchrony in (ASP).NET

Aliaksandr FaminShurickFomin@gmail.com

@AlexSane

Developer and a Kettle

Developer and a Kettle

1. Wait2. Make someone to wait3. Check periodically4. Make someone to

check5. Put a whistle on a

kettle6. Add a web-interface to

a kettle

1. Sync2. Sync with threads3. Async-sync4. Async with threads

5. Async with callbacks

6. Async with events

Comparison

Approach Transferring 1K,rps

Transferring 1M,rps

Sync 2844,44 100% 32,57 26%

Async with callbacks 2547,26 90% 125,97 100%

Async-sync 2327,28 82% 33,04 26%

Sync with threads 861,23 30% 83,89 67%

Async with threads 604,84 21% 80,36 64%

Evolution: WinAPI• struct OVERLAPPED (IAsyncResult)

• OVERLAPPED_COMPLETION_ROUTINE

(AsyncCallback)

6

Evolution: .NET 1.0 – 1.1• IAsyncResult

• AsyncCallback

• BeginXXX(@params, callback, userState)

• EndXXX(asyncResult)

7

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

IAsyncResult1. Callbacks are not thread

safe2. No context in callbacks (i.e.

no HttpContext)

3. Complexity of chaining (custom IAsyncResult, etc.)

4. Poor support of components

Events1. Event handlers are under

lock2. HttpContext available

3. Chaining is simple4. Component-oriented

ContextAwareResult, but no guarantee

SyncronizationContext

Event-based async pattern

Thread #1 XAsync YAsync

Thread #3 YCompleted

Thread #2 ZAsync

Thread #4 ZCompleted

PreRenderComplete

PreRender

AsyncOperationManagerX Y

XCompleted

Z

All operations arecompleted

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 carefullystatic void Main(string[] args){ var asyncResult = component.BeginSomeOperation(

parameter, Callback, state);}

void Callback(IAsyncResult aresult){ bool result = component.EndOperation(aresult); object state = asyncResult.AsyncState;}

TTT#3: Unsubscribe from eventsstatic void Main(string[] args){ component.OperationCompleted += component_OperationCompleted; component.OperationAsync("data", null);}

static void component_OperationCompleted(object sender, EventArgs e){ component.OperationCompleted -= component_OperationCompleted;}

TTT#5: There is no timeout support in both async patterns

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.

Q&A

Recommended