网站配色的方案,wordpress银行模板,深圳市年年卡网络科技公司是什么,沧浪seo网站优化软件默认情况下#xff0c;一个线程的特定指令相对于另一个线程中的指令的执行时机是不确定的#xff0c;如果想要对这种不确定性进行控制#xff0c;其中一种办法就是使用重置事件#xff08;虽然称为事件#xff0c;但是跟C#的委托跟事件没关系#xff09;。
重置事件用于…默认情况下一个线程的特定指令相对于另一个线程中的指令的执行时机是不确定的如果想要对这种不确定性进行控制其中一种办法就是使用重置事件虽然称为事件但是跟C#的委托跟事件没关系。
重置事件用于强迫代码等候另一个线程的执行直到获得事件已发生的通知。
重置事件类型包括ManualResetEvent、ManualResetEventSlim以及AutoResetEvent但在使用过程中应该尽量用前面两种类型而避免使用AutoResetEvent。
ManualResetEvent
ManualResetEvent对象具有两种状态非信号状态及信号状态。
当ManualResetEvent对象处于非信号状态调用WaitOne方法则当前线程会被阻塞直到此ManualResetEvent对象调用Set方法后线程才被释放。当ManualResetEvent对象处于信号状态调用WaitOne方法时当前线程不会被阻塞ManualResetEvent立即释放线程并返回到非信号状态。
一、常用成员
构造函数
ManualResetEvent(Boolean)ManualResetEvent的构造函数参数为false则创建的ManualResetEvent对象为非信号状态反之为信号状态。
常用方法
boolean WaitOne()如果当前ManualResetEvent对象为非信号状态阻塞当前线程直到收到信号调用Set()方法如果当前的ManualResetEvent对象为信号状态则不会阻塞当前线程。
收到信号或当前对象为信号状态时返回true否则一直等待不会返回。
bool WaitOne([int millisecondsTimeout])如果当前ManualResetEvent对象为非信号状态阻止当前线程直到超过指定时间或收到信号某处调用了此对象的Set()如果当前的ManualResetEvent对象为信号状态则不会阻塞当前线程。
收到信号返回true否则返回false。
bool Set()将状态设置为信号状态允许一个或多个等待线程继续。
操作成功返回true否则false。
bool Reset()将状态设置为非信号状态。
如果该操作成功返回true否则false。
Dispose()释放WaitHandle类ManualResetEvent为其子类的当前实例所使用的所有资源。
二、示例
ManualResetEvent manualResetEvent new ManualResetEvent(false);Socket server new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(IPAddress.Any, 9090));
server.Listen();server.BeginAccept(new AsyncCallback(asyncResult
{Socket s asyncResult.AsyncState as Socket;Socket ct s.EndAccept(asyncResult);while (true){manualResetEvent.Reset();byte[] buffer new byte[1024];ct.BeginReceive(buffer, 0, 1024, SocketFlags.None, new AsyncCallback(asyncResult {Socket c asyncResult.AsyncState as Socket;c.EndReceive(asyncResult);manualResetEvent.Set();}), ct);manualResetEvent.WaitOne();Console.WriteLine(Encoding.UTF8.GetString(buffer));}
}), server);Socket client new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(new IPEndPoint(IPAddress.Parse(127.0.0.1), 9090));
for (int i 0; i 10; i)
{//Thread.Sleep(20); //如果有个延时就可以看到不粘包client.Send(Encoding.UTF8.GetBytes(Hello));
}Console.ReadLine();三、注意
释放资源
官方文档中说明实现 IDisposable接口。 在使用完类型后应直接或间接释放类型。 若要直接释放类型请在 try/catch块中调用其Dispose方法。 若要间接释放类型请使用 using。 因此在使用过程中可以的话尽量考虑资源的释放。
ManualResetEventSlim
ManualResetEvent和ManualResetEventSlim的区别在于前者默认使用核心同步而后者进行了优化除非万不得已否则会尽量避免使用核心机制因此ManualResetEventSlim的性能更好。因此一般情况下应选用ManualResetEventSlim除非要等待多个事件或需跨越多个进程。
此外用了一下发现ManualResetEventSlim用的是Wait()而不是WaitOne()两者比较大的区别在于Wait()还可以接收一个取消令牌。
AutoResetEvent
AutoResetEvent类表示线程同步事件在一个等待线程释放后收到信号时自动重置
注意AutoResetEvent对象调用Set()后会自动调用Reset()方法这也是类名的由来而ManualResetEvent其功能跟AutoResetEvent是一样的只是在调用Set()方法后不会自动调用Reset()方法。此外AutoResetEvent只解除一个线程的Wait()调用所造成的阻塞使用自动重置事件很容易在编写生产者线程时发生失误导致它的迭代次数多于消费者线程。
实际上应该尽量避免使用AutoResetEvent而选择使用ManualResetEvent和ManualResetEventSlim。
官方示例 using System;
using System.Threading;// Visual Studio: Replace the default class in a Console project with
// the following class.
class Example
{private static AutoResetEvent event_1 new AutoResetEvent(true);private static AutoResetEvent event_2 new AutoResetEvent(false);static void Main(){Console.WriteLine(Press Enter to create three threads and start them.\r\n The threads wait on AutoResetEvent #1, which was created\r\n in the signaled state, so the first thread is released.\r\n This puts AutoResetEvent #1 into the unsignaled state.);Console.ReadLine();for (int i 1; i 4; i){Thread t new Thread(ThreadProc);t.Name Thread_ i;t.Start();}Thread.Sleep(250);for (int i 0; i 2; i){Console.WriteLine(Press Enter to release another thread.);Console.ReadLine();event_1.Set();Thread.Sleep(250);}Console.WriteLine(\r\nAll threads are now waiting on AutoResetEvent #2.);for (int i 0; i 3; i){Console.WriteLine(Press Enter to release a thread.);Console.ReadLine();event_2.Set();Thread.Sleep(250);}// Visual Studio: Uncomment the following line.//Console.Readline();}static void ThreadProc(){string name Thread.CurrentThread.Name;Console.WriteLine({0} waits on AutoResetEvent #1., name);event_1.WaitOne();Console.WriteLine({0} is released from AutoResetEvent #1., name);Console.WriteLine({0} waits on AutoResetEvent #2., name);event_2.WaitOne();Console.WriteLine({0} is released from AutoResetEvent #2., name);Console.WriteLine({0} ends., name);}
}实际用例 下面是下载文件的一部分代码遍历文件列表每一个文件开始下载后就阻塞当前线程直到文件下载完成后再释放线程。
private AutoResetEvent autoResetEvent new AutoResetEvent(false);
private void OnStart()
{Task.Run(() {Files.ToList().ForEach(f {WebAccess webAccess new WebAccess();webAccess.DownloadProgressChanged (int progressPercent) {Progress progressPercent; //设置进度泡泡};webAccess.DownLoadCompleted () {autoResetEvent.Set();};webAccess.Download(f, $.\{f.FileName});autoResetEvent.WaitOne();});});
}