windows phone 8 - 3.5 async programming

26
Oliver Scheer Senior Technical Evangelist Microsoft Deutschland http://the-oliver.com Async and Await Programming on Windows Phone 8 await async

Upload: oliver-scheer

Post on 10-May-2015

1.274 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Windows Phone 8 - 3.5 Async Programming

Oliver Scheer

Senior Technical Evangelist

Microsoft Deutschland

http://the-oliver.com

Async and Await Programming on Windows Phone 8

await

async

Page 2: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential2

Agenda

async and await in C#5 Task Programming Model

How awaitable objects work

The new way to do parallel processing

Replacing BackgroundWorker with async

Learn why you’ll never use Thread or Threadpool

again!

Page 3: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential3

•Windows Phone 7.1 Base Class Libraries used .NET 4.0 patterns to support

asynchronous programming• Async programming model: BeginXYZ, EndXYZ methods

• Example: HttpWebRequest BeginGetResponse and EndGetResponse methods• Event async pattern: Setup a Completed event handler, then call XYZAsync() to start

operation• Example: WebClient DownloadStringAsync method and

DownloadStringCompleted event

• Windows Phone 8 includes many WinRT APIs• Any API that potentially takes more than 50ms to complete is exposed as an

asynchronous method using a new pattern: Task Programming Model• Asynchronous programming is a first class citizen of WinRT, used for File I/O,

Networking etc

• Task-based programming is becoming the way to write asynchronous code

• Many new APIs in Windows Phone 8 now and in the future will offer only a Task-based API

Async Methods and Task Programming Model

Page 4: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential4

Keeping UI Fast and FluidComparing blocking File I/O using WP7.1 with TPM File I/O in WP8

TIMEUI Thread

var isf = IsolatedStorageFile.GetUserStoreForApplication();

using (var fs = new IsolatedStorageFileStream(

"CaptainsLog.store", FileMode.Open,

isf))

{

StreamReader reader = new StreamReader(fs);

theData = reader.ReadToEnd();

reader.Close();

};

Page 5: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential5

StorageFile storageFile = await

Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(

new Uri("ms-appdata:///local/CaptainsLog.store "));

Stream readStream = await StorageFile.OpenStreamForReadAsync();

using (StreamReader reader = new StreamReader(readStream))

{

theData = await reader.ReadToEndAsync();

}

Keeping UI Fast and FluidComparing blocking File I/O using WP7.1 with TPM File I/O in WP8

TIMEUI Thread

Page 6: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential6

Making Asynchronous Code Look Synchronous

private async Task<string> LoadFromLocalFolderAsync()

{

StorageFile storageFile = await

Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(

new Uri("ms-appdata:///local/CaptainsLog.store "));

Stream readStream = await

storageFile.OpenStreamForReadAsync();

using (StreamReader reader = new StreamReader(readStream))

{

theData = await reader.ReadToEndAsync();

}

}

Original Context ThreadpoolTIME

Page 7: Windows Phone 8 - 3.5 Async Programming

Simpler for Developers to Write Asynchronous Code

04/11/2023

Microsoft confidential7

private async void SomeMethod()

{

string theData = await LoadFromLocalFolderAsync();

TextBox1.Text = theData;

}

private async Task<string> LoadFromLocalFolderAsync()

{

...

} All Async methods

must return void, Task or Task<TResult>

Caller can use the await keyword to pause until

the async operation has completed execution on

a Threadpool thread

It automatically marshals back to the originating context,

so no need to use the Dispatcher to set UI

objects on the UI thread

All methods that contain calls to

awaitables must be declared using the

async keyword

When the async code completes , it ‘calls back’ and resumes

where it left off, passing back the

return value

Page 8: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential8

•Marking a method with the async keyword causes the C# or Visual Basic

compiler to rewrite the method’s implementation using a state machine

•Using this state machine the compiler can insert points into the method at

which the method can suspend and resume its execution without blocking a

thread

• These points are inserted only where you explicitly use the await keyword

•When you await an asynchronous operation that’s not yet completed:• Compiler packages up all the current state of the calling method and preserves it on

the heap• Function returns to the caller, allowing the thread on which it was running to do

other work• When the awaited operation later completes, the method’s execution resumes using

the preserved state

Compiler Transformations

Page 9: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential9

private async void SomeMethod()

{

string theData = await LoadFromLocalFolderAsync();

TextBox1.Text = theData;

}

Freeing Up the Calling Thread

Page 10: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential10

private async void SomeMethod()

{

await LoadFromLocalFolderAsync();

[Preserve state on heap]

}

[Calling thread free to do other work]

Freeing Up the Calling Thread

[Calling thread free to do other work]

[Calling thread free to do other work]

[Calling thread free to do other work]

Page 11: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential11

{

[Restore Context]

string theData = [Result from LoadFromLocalFolder()]

TextBox1.Text = theData;

}

private async void SomeMethod()

{

await LoadFromLocalFolder();

[Preserve state on heap]

}

[Calling thread free to do other work]

Freeing Up the Calling Thread

[Calling thread free to do other work]

[Calling thread free to do other work]

[Calling thread free to do other work]

Page 12: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential12

• Error Handling is simpler• Just use try…catch around the async code, same as with synchronous code• Exceptions thrown while code is executing asynchronously are surfaced back on the

calling thread

private async void SomeMethod()

{

try

{

string theData = await LoadFromLocalFolder();

TextBox1.Text = theData;

}

catch (Exception ex)

{

// An exception occurred from the async operation

}

}

Error Handling

Page 13: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential13

•No, you can call async methods without await• Called method still executes on background thread• The calling thread does not wait for the result•Only feasible for async methods that return void or Task, not

Task<TResult>

• Intellisense warns you when you do this

Must I use await with async methods?

Page 14: Windows Phone 8 - 3.5 Async Programming

Demo 1: async and await

Page 15: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential15

Replacing BackgroundWorker

Page 16: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential16

• If you have some long-running code that you want to execute on a background

thread, the BackgroundWorker class is a good solution• Still supported in Windows Phone 8!• Supports Cancellation and Progress reports

• You can get the same behaviour using Tasks

Executing Code on a Background Thread

Page 17: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential17

private void LaunchTaskButton_Click(object sender, RoutedEventArgs e)

{

BackgroundWorker bgw = new BackgroundWorker();

bgw.RunWorkerCompleted += ((s, a) =>

MessageBox.Show("BackgroundWorker has completed, result: " + (int)a.Result)

);

bgw.DoWork += ((s, a) =>

{

// Simulate some long running work

Thread.Sleep(5000);

// Return the result

a.Result = 1234;

});

// Now start execution

bgw.RunWorkerAsync();

}

BackgroundWorker

Page 18: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential18

• private async void LaunchTaskButton_Click(object sender, RoutedEventArgs e)

{

int result = await Task.Factory.StartNew<int>(() =>

{

// Simulate some long running work

Thread.Sleep(5000);

// Return the result

return 4321;

}

);

MessageBox.Show("BackgroundWorker has completed, result is: " + result);

}

Task Equivalent

Page 19: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential19

BackgroundWorker bgw = new BackgroundWorker();

bgw.WorkerReportsProgress = true;

bgw.RunWorkerCompleted += ((s, a) => MessageBox.Show("BackgroundWorker has completed, result: " +

(int)a.Result));

bgw.ProgressChanged += ((s, a) => {

// Progress Indicator value must be between 0 and 1

SystemTray.GetProgressIndicator(this).Value = (double)a.ProgressPercentage/100.0; });

bgw.DoWork += ((s, a) => {

// Simulate some long running work

for (int i = 0; i < 10; i++)

{

Thread.Sleep(500);

// Report progress as percentage completed

bgw.ReportProgress(i * 10);

}

a.Result = 1234; // Return the result

});

// Now start execution

bgw.RunWorkerAsync();

BackgroundWorker with Progress Reporting

Page 20: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential20

IProgress<int> progressReporter = new Progress<int>((percentComplete) =>

// Progress Indicator value must be between 0 and 1

SystemTray.GetProgressIndicator(this).Value = (double)percentComplete / 100.0 );

int result = await Task.Factory.StartNew<int>(() =>

{

// Simulate some long running work

for (int i = 0; i < 10; i++)

{

Thread.Sleep(500);

// Report progress as percentage completed

progressReporter.Report(i * 10);

}

// Return the result

return 4321;

} );

MessageBox.Show("BackgroundWorker has completed, result is: " + result);

Task with Progress Reporting

Page 21: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential21

BackgroundWorker bgw = new BackgroundWorker();

bgw.WorkerReportsProgress = true;

bgw.WorkerSupportsCancellation = true;

bgw.RunWorkerCompleted += ((s, a) =>

{

if (a.Cancelled)

MessageBox.Show("BackgroundWorker was cancelled");

else

MessageBox.Show("BackgroundWorker has completed, result: " + (int)a.Result);

} );

bgw.ProgressChanged += ((s, a) => { ... });

bgw.DoWork += ((s, a) =>

{

// Simulate some long running work

for (int i = 0; i < 10; i++)

{

Thread.Sleep(500);

// Report progress as percentage completed

bgw.ReportProgress(i * 10);

// Have we been cancelled?

BackgroundWorker with Cancellation

Page 22: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential22

bgw.DoWork += ((s, a) =>

{

// Simulate some long running work

for (int i = 0; i < 10; i++)

{

Thread.Sleep(500);

// Report progress as percentage completed

bgw.ReportProgress(i * 10);

// Have we been cancelled?

if (bgw.CancellationPending)

{

a.Cancel = true;

return;

}

} a.Result = 1234; // Return the result

});

// Now start execution

bgw.RunWorkerAsync();

BackgroundWorker with Cancellation

Page 23: Windows Phone 8 - 3.5 Async Programming

04/11/2023Microsoft confidential23

var cancellationTokenSource = new CancellationTokenSource();

var cancellationToken = cancellationTokenSource.Token;

try

{

int result = await Task.Factory.StartNew<int>(() =>

{

// Simulate some long running work

for (int i = 0; i < 10; i++)

{

Thread.Sleep(500);

// Have we been cancelled?

cancellationToken.ThrowIfCancellationRequested();

}

return 4321; // Return the result

}, cancellationToken);

MessageBox.Show("BackgroundWorker has completed, result is: " + result);

}

catch (OperationCanceledException ex) {

MessageBox.Show("Task BackgroundWorker was cancelled");

}

Task with Cancellation

Page 24: Windows Phone 8 - 3.5 Async Programming

Demo 2: BackgroundWorker vs Tasks

Page 25: Windows Phone 8 - 3.5 Async Programming

04/11/2023

• C#5 and VB.NET add first-class support for asynchronous programming

•Methods that return void, Task or Task<TResult> can be called using the

await modifier

• The await modifier causes the caller to suspend execution and wait for

completion of the async task

•When complete, the return result and any exceptions are automatically

marshalled back to the originating context

• Execution continues where it left off – makes async code appear synchronous!

•Methods that make calls using await must themselves be marked with the

async modifier

Summary

Page 26: Windows Phone 8 - 3.5 Async Programming

The information herein is for informational purposes only an represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be

interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.

© 2012 Microsoft Corporation.

All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.

MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.