Objective
Recently watching C # concurrent programming • Classic example "This book, this is not a theoretical book, but this is a main talk about how to better use the current c#.net for us to provide these APIs of a book, most of the book is some examples, in the daily development is often used.
Some of the ideas in the book agree, for example, the author said that most of the current books on the concurrent multithreading and other content in the end, but the lack of a introduction to concurrent Programming Guide and reference.
Another point of view is that most of the domestic technical staff think the bottom of the technology is a good, and to do the upper application is "code farmers", the author opposed this view, in fact, can use the existing library is also a kind of ability, although the understanding of the basic knowledge of daily life is still helpful, but it is best to learn from the more advanced abstract
Asynchronous Basics
Task paused, Hibernate
Asynchronous suspend or Hibernate task, can use Task.delay ();
Static Async task<t> delayresult<t> (T result, TimeSpan delay) { await task.delay (delay); return result;}
Asynchronous retry mechanism
A simple exponential backoff policy, the time to retry is incremented, and this strategy is generally used when accessing WEB services.
Static Async task<string> downloadstring (string uri) { using (var client = new HttpClient ()) { var nextdealy = Timespan.fromseconds (1); for (int i = 0; I! = 3; ++i) { try { return await client. Getstringasync (URI); } catch { } await Task.delay (nextdealy); Nextdealy = Nextdealy + nextdealy; } Last retry, throw an error message return await client. Getstringasync (URI);} }
Report Progress
In asynchronous operations, it is often necessary to show the progress of the operation, which can be iprocess<t> and process<t>.
Static Async Task Mymethodasync (iprogress<double> progress) { double precentcomplete = 0; bool done = false; while (!done) { await task.delay (+); if (progress! = null) { progress. Report (Precentcomplete); } precentcomplete++; if (Precentcomplete = =) {Done = true;}} } public static void Main (string[] args) { Console.WriteLine ("Starting ..."); var progress = new progress<double> (); Progress. ProgressChanged + = (sender, e) + = { Console.WriteLine (e); }; Mymethodasync (Progress). Wait (); Console.WriteLine ("Finished");}
Wait for a set of tasks
Perform several tasks at the same time, waiting for them all to complete
Task Task1 = Task.delay (timespan.fromseconds (1)); Task Task2 = Task.delay (Timespan.fromseconds (2)); Task task3 = Task.delay (timespan.fromseconds (1)); Task.whenall (Task1, Task2, TASK3). Wait ();
Wait for any one task to complete
To perform several tasks, you only need to respond to one of the finishes. It is mainly used for a variety of independent attempts at an operation, as long as one of the attempts is complete and the task is completed.
Static Async task<int> Firstresponseurlasync (String Urla, String urlb) { var httpClient = new HttpClient ();
task<byte[]> Downloadtaska = Httpclient.getbytearrayasync (Urla); task<byte[]> DOWNLOADTASKB = Httpclient.getbytearrayasync (URLB); Task<byte[]> Completedtask = await task.whenany (Downloadtaska, DOWNLOADTASKB); byte[] data = await completedtask; return data. Length;}
Collection
Immutable Stacks and queues
Requires a stack and queue that is not constantly modified and can be accessed securely by multiple threads. Their APIs are very similar to stack<t> and queue<t>. In performance, immutable stacks (LIFO) and queues (FIFO) have the same time complexity as standard stacks and queues. However, in simple cases where frequent modifications are required, standard stacks and queues are faster.
On an internal implementation, when an object is overwritten (re-assigned), the immutable collection takes the return of a modified set, and the original collection reference does not change, that is, if another variable references the same object, then it (the other variable) does not change.
Immutablestack
var stack = Immutablestack<int>. Empty;stack = stack. Push (one); var biggerstack = stack. Push (n); foreach (var item in Biggerstack) { Console.WriteLine (item);} Output:12 11int lastitem;stack = stack. Pop (out LastItem); Console.WriteLine (LastItem); Output:11
In fact, two stacks internally share memory of 11, which is very efficient and thread-safe for each instance.
Immutablequeue
var queue = Immutablequeue<int>. Empty;queue = queue. Enqueue (one); queue = queue. Enqueue (n); foreach (var item in queue) { Console.WriteLine (item);}//Output:11 12int nextitem;queue = queue. Dequeue (out Nextitem); Console.WriteLine (Nextitem); Output:11
Immutable lists and collections
Immutablelist
Complexity of Time
There are times when you need a data structure that supports indexing, does not change frequently, and can be accessed by multithreaded security.
var list = Immutablelist<int>. Empty;list = list. Insert (0, one); list = list. Insert (0, N); foreach (var item in list) { Console.WriteLine (item);}//12 11
Immutablelist<t> can be indexed, but pay attention to performance issues and cannot be used to simply replace List<t>. Its internal implementation is to use the data of the two-tree organization, which is done to allow the memory to be shared between different instances.
Immutablehashset
There are times when you need a data structure that does not need to store duplicate content, is not frequently modified, and can be accessed securely by multiple threads. Time complexity O (log N).
var set = Immutablehashset<int>. Empty;set = set. ADD (one); set = set. ADD (n); foreach (var item in set) { Console.WriteLine (item);}//11 12 Indeterminate order
Thread-Safe dictionaries
A thread-safe set of key-value pairs that can still be synchronized for multiple threads to read and write.
Concurrentdictionary
Blended with fine-grained locking and lock-free technology, it is one of the most useful collection types.
var dictionary = new Concurrentdictionary<int, string> ();d ictionary. AddOrUpdate (0, key = "zero", (key, OldValue) = "Zero");
If multiple threads read and write a shared collection, the utility concurrentdictionary<tkey,tvalue> is the most appropriate. If it is not frequently modified, it is more appropriate to use immutabledictionary<tkey,tvalue>.
It is best used when you need to share data, where multiple threads share a collection, and if some threads only add elements and some threads only remove elements, it is best to use a producer/consumer collection (blockingcollection<t>).
Initializing shared resources
The program uses a value in multiple places and initializes it the first time it is accessed.
static int _simplevluae;static readonly lazy<task<int>> shardasyncinteger = new Lazy<task<int >> (Async () = { await Task.delay (2000). Configureawait (false); return _simplevluae++; }); public static void Main (string[] args) { int sharevalue = ShardAsyncInteger.Value.Result; Console.WriteLine (Sharevalue); 0 sharevalue = shardAsyncInteger.Value.Result; Console.WriteLine (Sharevalue); 0 sharevalue = shardAsyncInteger.Value.Result; Console.WriteLine (Sharevalue); 0}
The above is C # concurrent programming • Classic example reading notes content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!