Profile
When multiple tasks or threads run in parallel, it is difficult to avoid concurrent access to certain limited resources. You might consider using semaphores to do this control (System.Threading.Semaphore) is a semaphore object that represents a Windows kernel. If you expect to wait a short time, consider using Semaphoreslim, which is less expensive.
. The semaphore in the NETFramework coordinates access to the resource by tracking the task or thread that enters and leaves. Semaphores need to know the maximum number of resources, when a task enters, the resource counter is reduced by 1, when the counter is 0 o'clock, if there is a task to access the resource, it will be blocked until a task leaves.
Sample program: 10 Tasks parallel access to 3 resources
usingSystem;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.diagnostics;namespace sample5_8_semaphoreslim{class Program {Private Static int_tasknum =Ten;Private StaticTask[] _tasks;Private Const intMax_resource =3;Private Const intRun_loop =Ten;Private StaticSemaphoreslim M_semaphore;Private Static void Work1(intTaskID) {inti =0;varSW = Stopwatch.startnew ();varRnd =NewRandom (); while(I < Run_loop) {Thread.Sleep (RND). Next ( $, -)); Console.WriteLine ("TASK"+ TaskID +"Requesting {"); M_semaphore.wait ();Try{Console.WriteLine ("TASK"+ TaskID +"Working ..."+ i); Sw. Restart (); Thread.Sleep (RND). Next ( $, -)); }finally{Console.WriteLine ("TASK"+ TaskID +"Requesting}"); M_semaphore.release (); i++; } } }Static voidMain (string[] args) {_tasks =NewTask[_tasknum]; M_semaphore =NewSemaphoreslim (Max_resource);inti =0; for(i =0; i < _tasknum; i++) {_tasks[i] = Task.Factory.StartNew (num) + = {varTaskID = (int) Num; Work1 (TaskID); }, I); }varFinaltask = Task.Factory.ContinueWhenAll (_tasks, (Tasks) = {Task.waitall (_tasks); Console.WriteLine ("=========================================================="); Console.WriteLine ("All Phase are completed"); Console.WriteLine ("=========================================================="); });Try{finaltask.wait (); }Catch(AggregateException AEX) {Console.WriteLine ("Task failed and Canceled"+ AEX. ToString ()); }finally{M_semaphore.dispose (); } console.readline (); } }}
Use timeouts and cancellations
The semaphore, of course, cannot be permanently blocked there. The semaphore also provides a timeout processing mechanism. The method is to pass in the wait function a timeout wait time-wait (int timeout). When the wait return value is False, it indicates that it timed out. If 1 is passed in, it indicates an indefinite wait.
Example of a program: note that m_semaphore.release () is commented out, the task waits 1 seconds and then times out.
usingSystem;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.diagnostics;namespace sample5_8_semaphoreslim{class Program {Private Static int_tasknum =Ten;Private StaticTask[] _tasks;Private Const intMax_resource =3;Private Const intRun_loop =Ten;Private StaticSemaphoreslim M_semaphore;Private Static void Work1(intTaskID) {inti =0;varSW = Stopwatch.startnew ();varRnd =NewRandom (); while(I < Run_loop) {Thread.Sleep (RND). Next ( $, -)); Console.WriteLine ("TASK"+ TaskID +"Requesting {");if(!m_semaphore.wait ( +) {Console.WriteLine ("TASK"+ TaskID +"TIMEOUT!!!");return; }Try{Console.WriteLine ("TASK"+ TaskID +"Working ..."+ i); Sw. Restart (); Thread.Sleep (RND). Next ( -, the)); }finally{Console.WriteLine ("TASK"+ TaskID +"Requesting}");//m_semaphore.release ();i++; } } }Static voidMain (string[] args) {_tasks =NewTask[_tasknum]; M_semaphore =NewSemaphoreslim (Max_resource);inti =0; for(i =0; i < _tasknum; i++) {_tasks[i] = Task.Factory.StartNew (num) + = {varTaskID = (int) Num; Work1 (TaskID); }, I); }varFinaltask = Task.Factory.ContinueWhenAll (_tasks, (Tasks) = {Task.waitall (_tasks); Console.WriteLine ("=========================================================="); Console.WriteLine ("All Phase are completed"); Console.WriteLine ("=========================================================="); });Try{finaltask.wait (); }Catch(AggregateException AEX) {Console.WriteLine ("Task failed and Canceled"+ AEX. ToString ()); }finally{M_semaphore.dispose (); } console.readline (); } }}
Synchronization across a process or AppDomain
If you need to have synchronization across processes or AppDomain, consider using semaphore. Semaphore is the amount of semaphore acquired by the Windows kernel, so it is valid throughout the system.
It is the main interface when release and WaitOne, using the way and Semaphoreslim are consistent.
C # Parallel programming restricts concurrent access to resources using Semaphoreslim