2. Threading model was introduced in which release of .NET framework?
1.0
1.1
2.0
3.5
3.5 SP1
2) Interlocked class introduced in which release of .NET framework?
2.0
4.0
3.5 SP1
4.5
1.1
3) Can you stop an Asynchronous delegate?
Yes
No
It depends on implementation.
It depends on .NET framework version.
4) By Default .NET application starts how many threads?
1
2
3
Depends on processor architecture.
3. Asynchronous operations are operations which are
initiated and then continue concurrently with the
invoking code.
When conforming to the .NET Task-Based Asynchronous
Pattern (TAP), asynchronous methods return a task that
represents the ongoing operation and allows waiting for
its eventual outcome.
Invoking and then asynchronously waiting for a task-
returning method to complete is as simple as “await
myAsyncMethod();”. The control flow is completely
unaltered, and there are no callbacks in sight because the
compiler takes care of creating and signing them up.
4. Convert synchronous code into asynchronous
code
Perform tasks without blocking the UI
Run concurrent tasks
Implement cancellation and polling features
Generate a DLL library that exposes
asynchronous methods
5. Initiation and completion of an asynchronous
operation in the TAP are represented by a single
method, and thus there is only one method to
name. This is in contrast to the IAsyncResult
pattern, or APM pattern, where BeginMethodName
and EndMethodName methods are required, and in
contrast to the event-based asynchronous pattern,
or EAP, where a MethodNameAsync is required in
addition to one or more events, event handler
delegate types, and EventArg-derived types.
Asynchronous methods in the TAP are named with
an “Async” suffix that follows the operation’s name,
e.g. MethodNameAsync.
6. The singular TAP method returns either a Task
or a Task<TResult>, based on whether the
corresponding synchronous method would
return void or a type TResult, respectively. (If
adding a TAP method to a class that already
contains a method MethodNameAsync, the
suffix “TaskAsync” may be used instead,
resulting in “MethodNameTaskAsync”.)
7. public class MyClass
{
public IAsyncResult BeginRead(
byte [] buffer, int offset, int count,
AsyncCallback callback, object state);
public int EndRead(IAsyncResult asyncResult);
}
8. public class MyClass
{
public void ReadAsync(byte [] buffer, int offset, int count);
public event ReadCompletedEventHandler ReadCompleted;
}
public delegate void ReadCompletedEventHandler(
object sender, ReadCompletedEventArgs eventArgs);
public class ReadCompletedEventArgs : AsyncCompletedEventArgs
{
public int Result { get; }
}
9. TAP counterpart would expose the following
single method:
public class MyClass
{
public Task<int> ReadAsync(byte [] buffer, int
offset, int count);
}
10. The parameters to a basic TAP method should be
the same parameters provided to the synchronous
counterpart, in the same order.
However, “out” and “ref” parameters are exempted
from this rule and should be avoided entirely.
Any data that would have been returned through
an out or ref parameter should instead be returned
as part of the returned Task<TResult>’s Result,
utilizing a tuple or a custom data structure in order
to accommodate multiple values.
11. To expose a cancelable asynchronous operation,
a TAP implementation provides an overload that
accepts a CancellationToken after the
synchronous counterpart method’s parameters.
By convention, the parameter should be named
“cancellationToken”.
12. public Task<int> ReadAsync(
byte [] buffer, int offset, int count,
CancellationToken cancellationToken);
If the token has cancellation requested and the
asynchronous operation is able to respect that
request, the returned task will end in the
TaskStatus.Canceled state; there will be no
available Result and no Exception
13. In the TAP, progress is handled through an IProgress<T> interface
passed into the asynchronous method as a parameter named
“progress”.
Providing the progress interface at the time of the asynchronous
method’s invocation helps to eliminate race conditions that result
from incorrect usage where event handlers incorrectly registered after
the invocation of the operation may miss updates.
More importantly, it enables varying implementations of progress to
be utilized, as determined by the consumer
15. A single IProgress<T> implementation, Progress<T>, is
provided built-in (more implementations may be provided in
the future). The Progress<T> class is declared as follows:
public class Progress<T> : IProgress<in T>
{
public Progress();
public Progress(Action<T> handler);
protected OnReport(T value);
public event ProgressEventHandler<T> ProgressChanged;
}
16. public Task MethodNameAsync(…);
public Task MethodNameAsync(…, CancellationToken cancellationToken);
public Task MethodNameAsync(…, IProgress<T> progress);
public Task MethodNameAsync(…,
CancellationToken cancellationToken, IProgress<T> progress);
17. PatternsandTypes
From APM to Tasks
From Tasks to APM
Tasks and the Event-based Asynchronous
Pattern (EAP)
Tasks and WaitHandles
From Tasks to WaitHandles
18. The .NET Framework 1.0 saw the introduction of the
IAsyncResult pattern, otherwise known as the Asynchronous
Programming Model (APM) pattern, or the Begin/End
pattern.
The .NET Framework 2.0 then brought with it the event-based
asynchronous pattern (EAP).
The new TAP deprecates both of its predecessors, while at the
same time providing the ability to easily build migration
routines from the APM and EAP to TAP.
19. The APM pattern relies on two corresponding methods
to represent an asynchronous operation:
BeginMethodName and EndMethodName. At a high-
level, the begin method accepts as parameters to the
method the same parameters that would be supplied
to the MethodName synchronous method counterpart,
as well as also accepting an AsyncCallback delegate
and an object state
20. The begin method then returns an IAsyncResult, which
returns from its AsyncState property the object state
passed to the begin method. When the asynchronous
operation completes, the IAsyncResult’s IsCompleted
will start returning true, and its AsyncWaitHandle will
be set.
21. Additionally, if the AsyncCallback parameter to the begin
method was non-null, the callback will be invoked and passed
the same IAsyncResult that was returned from the begin
method.
When the asynchronous operation does complete, the
EndMethodName method is used to join with the operation,
retrieving any results or forcing any exceptions that occurred
to then propagate. There are further details around the
IAsyncResult’s CompletedSynchronously property that are
beyond the scope of this document; for more information,
see MSDN
22. Given the very structured nature of the APM pattern, it
is quite easy to build a wrapper for an APM
implementation to expose it as a TAP implementation.
In fact, the .NET Framework 4 includes helper routines
in the form of TaskFactory.FromAsync to provide this
translation.
23. Consider the .NET Stream class and its BeginRead/EndRead
methods, which represent the APM counterpart to the
synchronous Read method:
public int Read(
byte [] buffer, int offset, int count);
…
public IAsyncResult BeginRead(
byte [] buffer, int offset, int count,
AsyncCallback callback, object state);
public int EndRead(IAsyncResult asyncResult);
24. Utilizing FromAsync, we can implement a TAP wrapper for this method as follows:
public static Task<int> ReadAsync(
this Stream stream, byte [] buffer, int offset, int count)
{
if (stream == null) throw new ArgumentNullException(“stream”);
return Task<int>.Factory.FromAsync(stream.BeginRead,
stream.EndRead,
buffer, offset, count, null);
}
25. This implementation that utilizes FromAsync is effectively equivalent to the following:
public static Task<int> ReadAsync(
this Stream stream, byte [] buffer, int offset, int count)
{
if (stream == null) throw new ArgumentNullException(“stream”);
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(buffer, offset, count, iar =>
{
try { tcs.TrySetResult(stream.EndRead(iar)); }
catch(OperationCanceledException) { tcs.TrySetCanceled(); }
catch(Exception exc) { tcs.TrySetException(exc); }
}, null);
return tcs.Task;
}
26. For cases where existing infrastructure expects code to
implement the APM pattern, it is also important to be
able to be able to take a TAP implementation and use it
where an APM implementation is expected.
27. public static IAsyncResult AsApm<T>(
this Task<T> task, AsyncCallback callback, object state)
{
if (task == null) throw new ArgumentNullException(“task”);
var tcs = new TaskCompletionSource<T>(state);
task.ContinueWith(t =>
{
if (t.IsFaulted) tcs.TrySetException(t.Exception.InnerExceptions)
else if (t.IsCanceled) tcs.TrySetCanceled();
else tcs.TrySetResult(t.Result);
if (callback != null) callback(tcs.Task);
});
return tcs.Task;
}
28. Now, consider a case where we have a TAP implementation:
public static Task<string> DownloadStringAsync(Uri url);
And we need to provide an APM implementation:
public IAsyncResult BeginDownloadString(Uri url, AsyncCallback callback, object state);
public string EndDownloadString(IAsyncResult asyncResult);
29. This is achievable with the following code:
public IAsyncResult BeginDownloadString(
Uri url, AsyncCallback callback, object state)
{
return DownloadStringAsync(url).AsApm(callback, state);
}
public string EndDownloadString(IAsyncResult asyncResult)
{
return ((Task<string>)asyncResult).Result;
}
30. The event-based asynchronous pattern relies on an
instance MethodNameAsync method which returns void,
accepts the same parameters as the synchronous
MethodName method, and initiates the asynchronous
operation.
Prior to initiating the asynchronous operation, event
handlers are registered with events on the same instance,
and these events are then raised to provide progress and
completion notifications. The event handlers are typically
custom delegate types that utilize event argument types
that are or that are derived from
ProgressChangedEventArgs and AsyncCompletedEventArgs.
31. public static Task<string> DownloadStringAsync(Uri url)
{
var tcs = new TaskCompletionSource<string>();
var wc = new WebClient();
wc.DownloadStringCompleted += (s,e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wc.DownloadStringAsync(url);
return tcs.Task;
}
32. While not an asynchronous pattern per-se,
advanced developers may find themselves
utilizing WaitHandles and the ThreadPool’s
RegisterWaitForSingleObject method to be
notified asynchronously when a WaitHandle is
set.
We can wrap RegisterWaitForSingleObject to
enable a task-based alternative to any
synchronous wait on a WaitHandle:
33. public static Task WaitOneAsync(this WaitHandle waitHandle)
{
if (waitHandle == null) throw new ArgumentNullException("waitHandle");
var tcs = new TaskCompletionSource<bool>();
var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle,
delegate { tcs.TrySetResult(true); }, null, -1, true);
var t = tcs.Task;
t.ContinueWith(_ => rwh.Unregister(null));
return t;
}
34. The Task class implements IAsyncResult, and its
IAsyncResult implementation exposes an
AsyncWaitHandle property which returns a WaitHandle
that will be set when the Task completes. As such,
getting a WaitHandle for a Task is accomplished as
follows:
WaitHandle wh =
((IAsyncResult)task).AsyncWaitHandle;
35. We will create a WPF application to download a
web page and find any link in the HTML. You will
write the code in the old way by using
synchronous calls and finally run the application
to see the disadvantages of this way of
programming
36. In this exercise, you will create a very simple application
that will download the HTML content of a web page and,
using regular expressions, search through that content
looking for any link. Then, you will display those links in a
ListBox. You will build this application in two ways. First,
you will build the application using synchronous code
and examine the issues with this implementation.
Second, you will modify that application to use the
asynchronous code so you can see how this
implementation addresses the issues with the first
version of the application.
37. try
{
var response = new HttpClient().Get("http://msdn.microsoft.com");
string result =
response.EnsureSuccessStatusCode().Content.ReadAsString();
this.textBox1.Text = result;
}
catch (Exception)
{
MessageBox.Show(ex.ToString());
}
38. Notice the window is unresponsive and the
button actually never disables because the UI is
blocked while it downloads the web page.
39. In the previous code, you are using the
asynchronous version of the Get method,
the GetAsync, which is a new method added by
the .NET Framework 4.5 and has different
signature since it returns aTask type object. A
task represents an asynchronous operation
which may complete at some point in the
future.
40. try
{
var response = new
HttpClient().GetAsync("http://msdn.microsoft.com");
string result =
response.EnsureSuccessStatusCode().Content.ReadAsStri
ng();
this.textBox1.Text = result;
...
41. Adding the await keyword tells the compiler to
asynchronously wait for the task returned from the
method call.
This means that the rest of the code will be executed as a
callback only after the awaited method completes.
Another thing to notice is that you do not need to
change your try-catch block in order to make this work,
as the exceptions that happen in the background or in
the foreground will still be caught without any extra work
using a handler provided by the framework.
42. try
{
var response = await new
HttpClient().GetAsync("http://msdn.microsoft.com");
string result =
response.EnsureSuccessStatusCode().Content.ReadAsStri
ng();
this.textBox1.Text = result;
43. The await operator is applied to a task in an asynchronous method to
suspend the execution of the method until the awaited task
completes. The task represents ongoing work.
The asynchronous method in which await is used must be modified by
the async keyword. Such a method, defined by using the async
modifier, and usually containing one or more await expressions, is
referred to as an async method.
The task to which the await operator is applied typically is the return
value from a call to a method that implements the Task-Based
Asynchronous Pattern. Examples include values of type Task or
Task<TResult>.
44. An await expression does not block the thread
on which it is executing. Instead, it causes the
compiler to sign up the rest of the async
method as a continuation on the awaited task.
Control then returns to the caller of the async
method. When the task completes, it invokes its
continuation, and execution of the async
method resumes where it left off.
45. An await expression does not block the thread on which it is executing.
Instead, it causes the compiler to sign up the rest of the async method as a
continuation on the awaited task. Control then returns to the caller of the
async method. When the task completes, it invokes its continuation, and
execution of the async method resumes where it left off.
An await expression can occur only in the body of an immediately enclosing
method, lambda expression, or anonymous method that is marked by an
async modifier. The term await serves as a contextual keyword only in that
context. Elsewhere, it is interpreted as an identifier. Within the method,
lambda expression, or anonymous method, an await expression cannot occur
in the body of a synchronous function, in a query expression, in the catch or
finally block of an exception handling statement, in the block of a lock
statement, or in an unsafe context.
46. private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
47. // The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
48. The async modifier indicates that the method,
lambda expression, or anonymous method that it
modifies is asynchronous. Such methods are
referred to as async methods.
An async method provides a convenient way to do
potentially long-running work without blocking the
caller's thread. The caller of an async method can
resume its work without waiting for the async
method to finish.
49. Typically, a method modified by the async keyword
contains at least one await expression or statement. The
method runs synchronously until it reaches the
firstawait expression, at which point it is suspended until
the awaited task is complete. In the meantime, control is
returned to the caller of the method. If the method does
not contain an await expression or statement, then it
executes synchronously. A compiler warning alerts you to
any async methods that do not contain await.
The async keyword is a contextual keyword. It is a
keyword when it modifies a method, a lambda
expression, or an anonymous method. In all other
contexts, it is interpreted as an identifier.
50. public async Task<int> ExampleMethodAsync()
{
// . . .
// At the await expression, execution in this method is suspended and,
// if AwaitedProcessAsync has not already finished, control returns
// to the caller of ExampleMethodAsync.
int exampleInt = await AwaitedProcessAsync();
// . . .
// The return statement completes the task. Any method that is
// awaiting ExampleMethodAsync can now get the integer result.
return exampleInt;
}
51. An async method can have a return type of void, Task,
or Task<TResult>. The method cannot declare
any ref or out parameters, although it can call methods that
have such parameters.
The void return type is used primarily to define event
handlers, where a void return type is required. An async
method that returns void cannot be awaited.
In other cases, you specify Task<T> for the return type of an
async method if the return statement of the method specifies
an operand of type T. You use Task if no meaningful value is
returned when the method is completed. You can think of
the Task return type as meaning "Task<void>." That is, a call
to the method returns a Task, but when the Task is
completed, any await expression that is awaiting
the Task evaluates to void.
52. // An event handler must return void.
private async void button1_Click(object sender, RoutedEventArgs e)
{
textBox1.Clear();
// SumPageSizesAsync returns a Task.
await SumPageSizesAsync();
textBox1.Text += "rnControl returned to button1_Click.rn";
}
53. // The following async lambda expression creates an equivalent anonymous
// event handler.
button1.Click += async (sender, e) => {
textBox1.Clear();
// SumPageSizesAsync returns a Task.
await SumPageSizesAsync();
textBox1.Text += "rnControl returned to button1_Click.rn";
}
54. // The following async method returns a Task<T>.
private async Task<byte[]> GetByteArrayAsync(Uri currentURI)
{
// Declare an HttpClient object.
HttpClient client = new HttpClient();
// The GetAsync method returns a Task(Of T), where T is an HttpResponseMessage.
Task<HttpResponseMessage> httpRMTask = client.GetAsync(currentURI);
// Await httpRMTask evaluates to an HttpResponseMessage object.
HttpResponseMessage httpRM = await httpRMTask;
// The following line can replace the previous two assignment statements.
//HttpResponseMessage httpRM = await client.GetAsync(currentURI);
// Throw an exception if the HttpResponseMessage contains an error code.
httpRM.EnsureSuccessStatusCode();
// Use ReadAsByteArray to access the content of the resource as a byte array.
return httpRM.Content.ReadAsByteArray();
}
55. Visual Studio 11 Developer Preview
http://msdn.microsoft.com/en-
us/vstudio/hh127353
http://msdn.microsoft.com/en-
us/library/hh156513(v=vs.110).aspx