Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Async Functions in the Framework Class Library

Personally, I love async functions because they are relatively easy to learn, simple to use, and they are supported by many types in the FCL. It is easy to identify async functions because, by convention, Async is suffixed onto the method’s name. In the Framework Class Library (FCL), many of the types that offer I/O operations offer XxxAsync methods.6 Here are some examples.

■ All the System.IO.Stream-derived classes offer ReadAsync, WriteAsync, FlushAsync, and

CopyToAsync methods.

 

■ All the System.IO.TextReader-derived classed offer ReadAsync, ReadLineAsync, ReadTo­ EndAsync, and ReadBlockAsync methods. And the System.IO.TextWriter-derived classes offer WriteAsync, WriteLineAsync, and FlushAsync methods.

■ The System.Net.Http.HttpClient class offers GetAsync, GetStreamAsync, GetByte­ ArrayAsync, PostAsync, PutAsync, DeleteAsync, and many more.

■ All System.Net.WebRequest-derived classes (including FileWebRequest, FtpWebRequest, and HttpWebRequest) offer GetRequestStreamAsync and GetResponseAsync methods.

■ The System.Data.SqlClient.SqlCommand class offers ExecuteDbDataReaderAsync, ExecuteNonQueryAsync, ExecuteReaderAsync, ExecuteScalarAsync, and ExecuteXml­ ReaderAsync methods.

■ Tools (such as SvcUtil.exe) that produce web service proxy types also generate XxxAsync

methods.

 

 

 
 

5 For this reason, if you try to mark your program’s entry point method (Main) as async, the C# compiler issues the fol- lowing error: an entry point cannot be marked with the 'async' modifier. If you put any await operators in your Main method, then your process’s primary thread would return from Main as soon as the first await operator exe- cutes. But because code that calls Main can’t get a Task to monitor it and wait for it to complete, the process would just terminate (because you’re returning from Main), and the rest of the code in Main would never execute at all. Fortunately, the C# compiler considers this an error to prevent this from happening.

6 WinRT methods follow the same naming convention and return an IAsyncInfo interface. Fortunately, the .NET Framework supplies extension methods that effectively cast an IAsyncInfo to a Task. For more information about using asynchronous WinRT APIs with async functions, see Chapter 25, “Interoperating with WinRT Components.”


For anyone who has been working with earlier versions of the .NET Framework, you may be famil- iar with some other asynchronous programming models that it offered. There is the programming model that used BeginXxx and EndXxx methods along with an IAsyncResult interface. And there is the event-based programming model that also had XxxAsync methods (that did not return Task objects) and invoked event handler methods when an asynchronous operation completed. These two asynchronous programming models are now considered obsolete and the new model using Task objects is the preferred model.

While looking through the FCL, you might notice some classes that are lacking XxxAsync methods and instead only offer BeginXxx and EndXxx methods. This is mostly due to Microsoft not having the time to update these classes with the new methods. In the future, Microsoft should be enhancing these classes so that they fully support the new model. However, until they do, there is a helper method that you can use to adapt the old BeginXxx and EndXxx model to the new Task-based model.



Earlier I showed the code for a client application that makes a request over a named pipe. Let me show the server side of this code now.

 

private static async void StartServer() { while (true) {

var pipe = new NamedPipeServerStream(c_pipeName, PipeDirection.InOut, ­1, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough);

 

// Asynchronously accept a client connection

// NOTE: NamedPipServerStream uses the old Asynchronous Programming Model (APM)

// I convert the old APM to the new Task model via TaskFactory's FromAsync method await Task.Factory.FromAsync(pipe.BeginWaitForConnection, pipe.EndWaitForConnection,

null);

 

// Start servicing the client, which returns immediately because it is asynchronous ServiceClientRequestAsync(pipe);

}

}

 

The NamedPipeServerStream class has BeginWaitForConnection and EndWaitForConnection methods defined, but it does not yet have a WaitForConnectionAsync method defined. Hopefully this method will be added in a future version of the FCL. However, all is not lost, because, as you see

in the preceding code, I call TaskScheduler’s FromAsync method, passing into it the names of the BeginXxx and EndXxx methods, and then FromAsync internally creates a Task object that wraps these methods. Now I can use the Task object with the await operator.7

 

 
 

7 TaskScheduler’s FromAsync method has overloads that accept an IAsyncResult in addition to overloads that ac- cept delegates to the BeginXxx and EndXxx methods. When possible, avoid the overloads that accept an IAsyncResult because they are less efficient.


For the old event-based programming model, the FCL does not include any helper methods to adapt this model into the new Task-based model. So you have to hand-code it. Here is code demon- strating how to wrap a WebClient (which uses the event-based programming model) with a Task­ CompletionSource so it can be awaited on in an async function.

 

private static async Task<String> AwaitWebClient(Uri uri) {

// The System.Net.WebClient class supports the Event­based Asynchronous Pattern var wc = new System.Net.WebClient();

 

// Create the TaskCompletionSource and its underlying Task object var tcs = new TaskCompletionSource<String>();

 

// When a string completes downloading, the WebClient object raises the

// DownloadStringCompleted event, which completes the TaskCompletionSource wc.DownloadStringCompleted += (s, e) => {

if (e.Cancelled) tcs.SetCanceled();

else if (e.Error != null) tcs.SetException(e.Error); else tcs.SetResult(e.Result);

};

 

// Start the asynchronous operation wc.DownloadStringAsync(uri);

 

// Now, we can the TaskCompletionSource’s Task and process the result as usual String result = await tcs.Task;

// Process the resulting string (if desired)...

 

return result;

}

 

 


Date: 2016-03-03; view: 911


<== previous page | next page ==>
Nbsp;   Async Function Extensibility | Nbsp;   Other Async Function Features
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.006 sec.)