Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 24

async magina rije za uspjeh

vae aplikacije
Bahrudin Hrnjica
Senior Developer
Microsoft MVP C#
HMDN

Agenda
6 znaajki za bolju implementaciju vae aplikacije

Umotavanja eventa u Task za poboljanje


kontrole toka koda
Podrka
TaskCompletionSource<T>

Koristi se za umotavanja operacija u Task klasu


A kad se umota, moemo je koristiti kao svaki drugi task objekat

Pattern
public Task<T> FooAsync()
{
var tcs = new
TaskCompletionSource<T>();
// schedule something
asynchronously
// to invoke tcs.Set*
return tcs.Task;

public Task
Task<T>
async
Delay(int
Task
RunAsync(Func<T>
RunStoryboardAsync(this
WaitForClickAsync(this
milliseconds)
func)
Button
Storyboard
button)
sb)
{
var tcs = new TaskCompletionSource<bool>();
TaskCompletionSource<T>();
RoutedEventHandler
EventHandler<object>
ThreadPool.QueueUserWorkItem(delegate
new
Timer(_ => tcs.SetResult(true)).Change(milliseconds,
handler
handler
= (s,e)
= (s,e)
=> =>
{
-1);
tcs.SetResult(true);
try { tcs.SetResult(func()); }
sb.Completed
button.Click
catch (Exception
+= handler;
e) {sb.Begin();
tcs.SetException(e); }
});
returntcs.Task;
await
tcs.Task;
}
sb.Completed
return
button.Click
tcs.Task;
-= handler;
}

#1

Umotavanje (Wrapping) Eventa u Task


za poboljanje kontrole toka koda

Taskovi na ekanju (awaiting tasks) su pogodni za implementaciju niza operacija koje


trebaju da se izvre.

Koristiti Cancellation za poboljanje odziva


aplikacije
Podrka u .NET
CancellationToken kao mehanizam za implamentaciju prekida u
aplikaciji

var cts = new CancellationTokenSource();

SomeMethod(cts.Token);
cts.Cancel();

Pattern

public async Task FooAsync()


{

await SomeDotNetAsync();
await SomeWinRTAsync();

public async Task FooAsync(CancellationToken


cancellationToken)
{

await SomeDotNetAsync(cancellationToken);
await SomeWinRTAsync().AsTask(cancellationToken);

#2

Koritenje Cancellation za poboljanje


odziva

Moderna aplikacija nije samo dranje UI slobodnog za korisniki odziv. Ona prije svega
treba da radi ono to korisnik eli u datom trenutku.

Biti paljiv sa Async Void


3 tipa za vraanje async metode
async void, async Task, & async Task<T>

async Task & async Task<T> - vraa upravlja za predstojei task


async void je tzv. fire-and-forget mehanizam

Preporuka
Koristiti async void metode samo za top-level entry points (npr. UI event
handlers)

(Koristiti await async Task-returning metode u ostalim sluajevima)

Izbjegavati prosljeivanje async lambde u void-returning delegate

(Ne prosljeivati async lambde u WinRT metode u koliko niste sigurni 101%)

#3

Izbjegavanje async void

Mnogi problem kod async koda uzrokovani su koritenjem async void neispravno.

Koritenje ConfigureAwait za Perf &


Odziv
SynchronizationContext

WindowsFormsSynchronizationContext (Post: Control.BeginInvoke)


DispatcherSynchronizationContext (Post: Dispatcher.BeginInvoke)
WinRTSynchronizationContext (Post: CoreDispatcher.RunAsync)
AspNetSynchronizationContext(Post: )

Kako radi await?


1. Zakai se na Current Context prije await
2. Kad se task zavri vrati se u isti Context gdje je i zapoeo

await ConfigureAwait(false)
Iskljuuje vraanje u poetni Context (prethodni sluaj 2)
Koristiti ConfigureAwait(false) na svim await pozivima u bibliotekama

#4

Koritenje ConfigureAwait
async
async voi
voidd button1_Click()
button1_Click()
{{
aw
DoWorkAsync().Wait();
aw ai
DoWorkAsync().Wait();
aittDoWorkAsync();
DoWorkAsync();
}}

async
async
Task
DoWorkAsync()
async Task
Task
DoWorkAsync()
async
TaskDoWorkAsync()
DoWorkAsync()
{
{{
{
aw
ttt
al
aw
ai
Task.Run().ConfigureAwait(f
alse);
se);
aw
ai
Task.Run();
awai
ai
tTask.Run().ConfigureAwait(f
Task.Run();
Consol
e.WriteLine("D
one
ttask");
Consol
e.WriteLine("D
one
ask");
CConsol
e.WriteLine("D
one
ttask");
onsol
e.WriteLine("D
one
ask");
}}
}

Use
ConfigureAwait(false)
}

2.
2. Task.Run
Task.Run schedules
schedules
3.
3. Await
Await captures
captures
1.
1. DoWorkAsync
DoWorkAsync
work
work to
to run
run on
on thread
thread
SynchronizationContext
4.
UI
blocks
waiting
SynchronizationContext
4.
UI
blocks
waiting
invoked
on
UI
thread
invoked on UI thread
pool
pool
for
and
for DoWorkAsyncDoWorkAsyncand hooks
hooks up
up aa
returned
continuation
returned Task
Task to
to
continuation to
to run
run when
when
6.
5.
6. UI
UI thread
thread still
still
5. Task.Run
Task.Run task
task completes
completes on
on pool
pool &
&
complete
task
completes
complete
task
completes
blocked
invokes
blocked waiting
waiting for
for
invokes continuation
continuation which
which Posts
Posts back
back
async
to
async operation
operation to
to
to UI
UI thread
thread
complete.
complete.
Deadlock!
Deadlock!
.ConfigureAwait(false)
.ConfigureAwait(false) avoids
avoids

deadlock.
deadlock.

Koritenje ConfigureAwait za bolji


odziv i prefrormanse

Koristiti UI nit samo onda kada je to stvarno potrebno.

Izbjegavati Sync preko Async, Async preko


Sync u bibliotekama

#5

ta asinhrono stvarno znai?


Sinhrono
Izvri neto ovdje i odmah.
Onda kad se izvri, tek tad mogu kontrolisati neto drugo.

Asinhrono
Inicijalizirati neto ovdje u odmah.
Mogu kontrolisati neto drugo odmah, iako mi prethodni kod nije
zavrio.

Sync vs Async
Pauza na 10 sekundi a zatim output Hello' na konzolu.

Synchronous

Asynchronous

public static void PausePrint() {


var end = DateTime.Now +
TimeSpan.FromSeconds(10);
while(DateTime.Now < end);
Console.WriteLine("Hello");
}

public static void


Task PausePrintAsync() {
return
ThreadPool.QueueUserWorkItem(_
Task.Run(() =>
=>
asyn
Mogui
c
PausePrint());
problem
over
}
skaliranja
sync

public static void PausePrint() {


Task t = PausePrintAsync(); sync
preko
t.Wait();
async
}

public
Task PausePrintAsync()
public static
static async
Task PausePrintAsync()
{
{
var tcs = new
await Task.Delay(10000);
TaskCompletionSource<bool>();
Console.WriteLine("Hello");
new Timer(_ => {
}
Console.WriteLine("Hello");

Mogui
problem
odziva
aplikacija

tcs.SetResult(true);
}).Change(10000, Timeout.Infinite);
return tcs.Task;
}

Izbjegavati Sync preko Async, Async


preko Sync u bibliotekama
Preporuka
Sufiks izmeu ostalog pomae korisniku da razumije implementaciju.
Koristiti NazivMetodeAsync if metoda nekoristi niti.

ak i kad se koristi return Task.Run(() => NazivMetode());

Koristiti NazivMetode if ne postoji brza async i kada treba izbjegavati


deadlock.

Nedefinisati Metodu sa async samo ako radi: FooAsync().Wait();

Izuzetci
Metode od .WinMD dllova (asemblia)
Preklapanja u hierarhiji klasa

#5

Koritenje alata u Visual Studio


Visual Studio 2013: debugiranje Async metoda
Step In
Step Over
Step Out

#6

Kretanja debugera kroz async metode

Ulazak u metodu ak i kad je asinhrona.

Async debugiranje u Visual Studio


2013
Visual Studio 2013: Call Stack Window
Obezbjeuje call stack kroz sve async take.

Visual Studio 2013: Tasks Window


Navigacijska lista svih aktivnih async operacija.

#7

Koritenje Call Stack i Task


Windows sa async

Vano znati kako se dolo do neke take u kodu i ta se deava pri tom.

Ne zaboravite ispuniti
upitnike.
ekaju vas vrijedne
nagrade!

You might also like