. Net multi-threaded programming (misuse point analysis),. net multi-threaded programming
1. Shared Variables
Incorrect syntax:
All tasks may share the same variable, so the output results may be the same.
public static void Error(){ for(int i=0;i<10;i++) { Task.Run(() => { Console.WriteLine("{0}", i); }); }}
Correct syntax:
Assign the variable I to the local variable temp so that each task uses different I values.
public static void Right(){ for (int i = 0; i < 10; i++) { int temp = i; Task.Run(() => { Console.WriteLine("{0}", temp); }); }}
2. Do not clear the resources required to suspend the task.
Incorrect syntax:
Asynchronous output of text content, so when StreamReader is not used up, the variable sr has left its scope and calls the Dispose method.
Public static void Error () {using (StreamReader sr = new StreamReader (@ "D: \ description .txt", Encoding. default) {Task. run () => {Console. writeLine ("output: {0}", sr. readLine ());});}}
Correct syntax:
Public static void Right () {using (StreamReader sr = new StreamReader (@ "D: \ description .txt", Encoding. default) {var task = Task. run () => {Console. writeLine ("output: {0}", sr. readLine () ;}); task. wait ();}}
3 avoid locking this, typeof (type), string
Correct practice: Define a private read-only field of the object type and lock it.
4 The number of waitHandles for WaitHandle. WaitAll must be less than or equal to 64
public static void Error(){ ManualResetEvent[] manualEvents = new ManualResetEvent[65]; try { for (int i = 0; i < 65; i++) { var temp = i; Task.Run(() => { manualEvents[temp] = new ManualResetEvent(false); Console.WriteLine("{0}", temp); manualEvents[temp].Set(); }); } WaitHandle.WaitAll(manualEvents); } catch (Exception ae) { Console.WriteLine(ae.Message); }}
5. Exceptions cannot be captured.
Try {var task = Task. run () => {throw new Exception ("throw Exception") ;}); // if the following line of code is injected, an Exception task cannot be thrown. wait ();} catch (Exception ex) {Console. writeLine (ex. message );}
6. whether to release Task Resources
We recommend that you call Dispose, but not calling it is not a serious error.
Note that resources cannot be released when a Task is in some state. Otherwise, an error is returned.
Public static void CatchException () {try {Console. writeLine ("START"); var task = Task. run () = >{// throw new Exception ("throw Exception") ;}); // note the following line of code to observe the Exception result // task. wait (); task. dispose (); Console. writeLine ("end");} catch (Exception ex) {Console. writeLine (ex. message );}}
7. deadlock demonstration
Assume that both tsak1 and task2 have successfully obtained the first lock before obtaining the second lock (for tsak1, the second lock requested by tsak1 is LockedObj2, and for task2 is LockedObj1, A deadlock occurs.
private static readonly Object LockedObj1 = new object();private static readonly Object LockedObj2 = new object();public static void LockShow(){ var task1 = Task.Run(() => { lock (LockedObj1) { Console.WriteLine("get LockedObj1"); lock (LockedObj2) { Console.WriteLine("get LockedObj2...."); } } }); var task2 = Task.Run(() => { lock (LockedObj2) { Console.WriteLine("get LockedObj2"); lock (LockedObj1) { Console.WriteLine("get LockedObj1...."); } } });}
The following two results can be obtained after multiple running: the first figure shows no deadlock, and the second figure shows a deadlock.
8. Do not call the Thread. Abort method.
The Task does not provide the Abort method. If you use the new TPL (. NET 4.0 or later), you will not think of this problem. Generally, CancellationToken is used to control the cancellation of the Task.
9 ensure that shared variables are safe
Run the command repeatedly and observe different results, as shown in.
public static void Func(){ string s = "ASDFGH"; Parallel.Invoke( () => { s = s.Replace("A", "1"); s = s.Replace("S", "1s"); }, () => { s = s.Replace("A", "2"); s = s.Replace("S", "2s"); }, () => { s = s.Replace("A", "3"); }); Console.WriteLine(s);}
10 processor excess application and insufficient application
Public static void Func () {ParallelOptions po = new ParallelOptions (); // overprovisioning application. The processor has only four logical kernels, the result shows that the concurrency is set to 10 and all logic kernels are working. The number of waiting tasks is greater than 0. po. maxDegreeOfParallelism = 10; // The application is insufficient. The processor has four logic kernels, but the degree of parallelism is specified as 3. Another idle kernel is not occupied (or may be occupied by other threads, assume that the other kernel is idle when the degree of parallelism is set to 3. maxDegreeOfParallelism = 3; List <int> list = new List <int> (); Parallel. forEach (list, po, m =>{// business });}
The above is all the content of this article. I hope this article will help you in your study or work. I also hope to provide more support to the customer's home!