Asynchrony in (ASP).NET

childlikenumberΑσφάλεια

5 Νοε 2013 (πριν από 4 χρόνια και 1 μήνα)

293 εμφανίσεις

Asynchrony in (ASP).NET

Aliaksandr Famin

ShurickFomin@gmail.com

@
AlexSane

Developer and a Kettle

Developer and a Kettle

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

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

IAsyncResult


1.
Callbacks are not thread
safe

2.
No
context in callbacks (i.e.
no
HttpContext
)


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

4.
Poor support of
components


Events

1.
Event handlers are
under

lock

2.
HttpContext

available



3.
Chaining is simple

4.
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

AsyncOperationManager

X

Y

XCompleted

Z

All operations are

completed

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

static

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 events

static

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