Concurrency in C # Cookbook notes

Source: Internet
Author: User

Pausing for a Period of time
Problem:
You need to (asynchronously) wait for a period of time. This can is useful when unit
Testing or implementing retry delays. This solution can also is useful for simple time‐
Outs.
Solution:
The task type has a static method, Delay that returns a task, completes after the
Specified time.

This example defines a task of completes asynchronously, for use with unit testing.
When faking a asynchronous operation, it ' s important to test at least synchronous
Success and asynchronous success as well as asynchronous failure. This example returns
A task used for the asynchronous success case:

Static Async Task<t> delayresult<t>(T result, TimeSpan delay) {await  Task. Delay (delay); return result;}

This next example are a simple implementation of an exponential backoff, which is, a retry
Strategy where you increase the delays between retries. Exponential Backoff is a best
Practice when working with Web services to ensure the server does not get flooded with
Retries.
For production code, I would recommend a more thorough solu‐
tion, such as the Transient Error handling Block in Microsoft ' s en‐
Terprise Library; The following code is just a simple example of
Task.delay usage.

Static Asynctask<string> Downloadstringwithretries (stringURI) { using(varClient =NewHttpClient ()) { //Retry after 1 second and then after 2 seconds and then 4.varNextdelay = TimeSpan. FromSeconds (1);  for(inti =0; I! =3; ++i) {Try { return awaitclient. Getstringasync (URI); } Catch { } awaitTask. Delay (Nextdelay); Nextdelay= Nextdelay +Nextdelay;} //Try One last time , allowing the error to propogate. return awaitclient. Getstringasync (URI); }}

This final example uses Task.delay as a simple timeout; In this case, the desired se‐
Mantics is to return NULL if the service does not respond within three seconds:

Static Asynctask<string> Downloadstringwithtimeout (stringURI) {using(varClient =NewHttpClient ()) {varDownloadtask =client. Getstringasync (URI);varTimeouttask = Task. Delay ( the);varCompletedtask =awaitTask. WhenAny (Downloadtask, timeouttask);if(Completedtask = =timeouttask)return NULL;return awaitdownloadtask;}}


Discussion
Task.delay is a fine option for unit testing asynchronous code or for implementing
Retry logic. However, if you need to implement a timeout, a cancellationtoken is usu‐
Ally a better choice.
See Also
Recipe 2.5 Covers how Task.whenany are used to determine which Task completes first.
Recipe 9.3 covers using CancellationToken as a timeout

2.2. Returning completed Tasks
problem
You need to implement a synchronous method with an asynchronous signature. This
situation can arise if is inheriting from a asynchronous interface or base class
but wish to implement I T synchronously. This technique was particularly useful when unit
testing asynchronous code, when you need a simple stub or mock for a Synchronous
Interface.
Solution
You can use Task.fromresult to create and return a new task<t> that's already com‐
Pleted with the S Pecified value

Interface imyasyncinterface{Task<int> getvalueasync ();} class   public task<int>return Task. Fromresult ();}}

2.3. Reporting Progress
Problem
You need to respond to progress when an asynchronous operation is executing.
Solution
Use the provided iprogress<t> and progress<t> types. Your Async method should
Take an iprogress<t> argument; The T is whatever type of progress your need to report

Static Async Task Mymethodasync (iprogress<doublenulldouble0   while (!  if NULL ) Progress. Report (PercentComplete); }}

Calling code can use it as such:

Static Async  varnew progress<double>+ = (sender, args)  =  Await  Mymethodasync (progress);}

By convention, the iprogress<t> parameter is NULL if the caller does not need
Progress reports, so is sure to the check for this in your async method.
Bear on mind that the iprogress<t>. Report method is asynchronous. This means
That Mymethodasync could continue executing before the progress is actually reported.
For this reason, it's best to define T as anImmutable TypeOr at least a value type. If T is
A mutable reference type, then you'll have the to create a separate copy yourself each time
You call Iprogress<t>. Report.
Progress<t> would capture the current context while it is constructed and would invoke its
Callback within that context. This means, if construct the progress<t> on the
UI thread, then you can update the UI from its callback, even if the asynchronous
Method is invoking the report from a background thread.
When the A method supports progress reporting, it should also make a best effort to support
Cancellation

If all the tasks has the same result type and they all complete successfully, then the
Task.whenall task would return an array containing all the task results:

Task Task1 = task. Fromresult (3= Task. Fromresult (5= Task. Fromresult (7); int await Task. WhenAll (Task1, Task2, TASK3); // "Results" contains {3, 5, 7}

There is a overload of Task.whenall that takes an IEnumerable of tasks; However, I
Do not recommend the it. Whenever I mix asynchronous code with LINQ, I
Find the code is clearer when I explicitly "reify" the sequence (i.e., evaluate the sequence,
Creating a Collection):

Static Asynctask<string> Downloadallasync (ienumerable<string>URLs) { varHttpClient =NewHttpClient ();//Define What the we ' re going to does for each URL. varDownloads = URLs. Select (url =httpClient. Getstringasync (URL)); //Note that no tasks has actually started yet//because the sequence is not evaluated.//Start all URLs downloading simultaneously.task<string>[] Downloadtasks =downloads. ToArray (); //Now the tasks has all started.//asynchronously wait for any downloads to complete. string[] Htmlpages =awaitTask. WhenAll (Downloadtasks); return string. Concat (htmlpages);}
//Returns the length of data at the first URL to respond.Private Static Asynctask<int> Firstrespondingurlasync (stringUrla,stringurlb) { varHttpClient =NewHttpClient ();//Start both downloads concurrently.task<byte[]> Downloadtaska =httpClient. Getbytearrayasync (Urla); Task<byte[]> DOWNLOADTASKB =httpClient. Getbytearrayasync (URLB); //Wait for either of the tasks to complete.task<byte[]> Completedtask =awaitTask. WhenAny (Downloadtaska, DOWNLOADTASKB); //Return The length of the data retrieved from the URL. byte[] data =awaitCompletedtask;returndata. Length;}
Static Asynctask<int> Delayandreturnasync (intval) { awaitTask. Delay (TimeSpan. FromSeconds (Val)); returnVal;}Static AsyncTask Awaitandprocessasync (task<int>Task) { varresult =awaittask; Trace. WriteLine (result);}//This method is now prints "1", "2", and "3".Static AsyncTask Processtasksasync () {//Create a sequence of tasks.task<int> Taska = Delayandreturnasync (2); Task<int> TASKB = Delayandreturnasync (3); Task<int> TASKC = Delayandreturnasync (1); vartasks =New[] {Taska, TASKB, TASKC};varProcessingtasks = ( fromTinchTasksSelectAwaitandprocessasync (t)). ToArray (); //Await All processing to complete awaitTask. WhenAll (processingtasks);}

Alternatively, this can written as:

Static Asynctask<int> Delayandreturnasync (intval) { awaitTask. Delay (TimeSpan. FromSeconds (Val)); returnVal;}//This method is now prints "1", "2", and "3".Static AsyncTask Processtasksasync () {//Create a sequence of tasks.task<int> Taska = Delayandreturnasync (2); Task<int> TASKB = Delayandreturnasync (3); Task<int> TASKC = Delayandreturnasync (1); vartasks =New[] {Taska, TASKB, TASKC};varProcessingtasks = tasks. Select (Asynct = { varresult =awaitT; Trace. WriteLine (result); }). ToArray (); //Await All processing to complete awaitTask. WhenAll (processingtasks);}

Concurrency in C # Cookbook notes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.