我们可以调用Reset()方法来重置该值

时间:2021-08-06 07:48:24

ManualResetEvent 和AutoResetEvent一样,,是此外一种.NET线程同步技术。


ManualResetEvent被用于在两个或多个线程间进行线程信号发送。


      多个线程可以通过挪用ManualResetEvent东西的WaitOne要领进入期待或梗阻状态。当控制线程挪用Set()要领,所有期待线程将恢复并继续执行。

ManualResetEvent是如何事情的

在内存中连结着一个bool值,如果bool值为False,则使所有线程梗阻,反之,如果bool值为True,则使所有线程退出梗阻。当我们创建ManualResetEvent东西的实例时,我们在函数结构中通报默认的bool值,以下是实例化ManualResetEvent的例子。

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

在上面代码中,我们初始化了一个值为False的ManualResetEvent东西,这意味着所有挪用WaitOne放的线程将被梗阻,直到有线程挪用了 Set() 要领。而如果我们用值True来对ManualResetEvent东西进行初始化,所有挪用WaitOne要领的线程并不会被梗阻,可以进行后续的执行。

WaitOne要领

该要领梗阻当前线程并期待其他线程发送信号。如果收到信号,它将返回True,反之返回False。以下演示了如何挪用该要领。

manualResetEvent.WaitOne();

在WaitOne要领的第二个重载版本中,我们可以指定当前线程期待信号的时间间隔。如果在时间间隔内,没有收到信号,要领将返回False并继续执行。以下代码演示了带时间间隔参数的WaitOne挪用。

bool isSignalled = manualResetEvent.WaitOne(TimeSpan.FromSeconds(5));


我们指定了5秒作为WaitOne要领的参数,如果manualResetEvent东西在5秒内收到信号,它将isSignalled赋值为False。

Set要领

该要领用于给所有期待线程发送信号。 Set() 要领的挪用使得ManualResetEvent东西的bool变量值为True,所有线程被释放并继续执行。下面是挪用的例子:

manualResetEvent.Set();


Reset要领
   一旦我们挪用了ManualResetEvent东西的Set()要领,它的bool值就变为true,我们可以挪用Reset()要领来重置该值,Reset()要领重置该值为False。以下是挪用Reset要领的例子:

manualResetEvent.Reset();


如果我们想多次发送信号,那么我们必需在挪用Set()要领后当即挪用Reset()要领。

ManualResetEvent 例子
    下面的例子展示了如何使用ManualResetEvent来释放多个线程。我们用false值实例化了ManualResetEvent东西,它将梗阻所有挪用WaitOne要领的线程。我们创建了两个线程,它们挪用要领GetDataFromServer,并以server数量作为参数。
      在挪用WaitOne要领获取第一批数量后,两个线程均期待来自挪用WaitOne线程的信号。当控制线程挪用manualrestEvent东西的Set要领,两个线程均被释放并继续运行。在挪用Set要领后,我们当即挪用了Reset要领,这将转变manualrestEvent东西的bool值为false。所以,如果线程再次挪用WaitOne要领,他们仍然会被梗阻。
    在从处事器获取第二批数据后,两个线程均挪用了WaitOne要领。在2秒后,控制线程再次挪用Set要领释放两个线程。

class Program { static ManualResetEvent manualResetEvent = new ManualResetEvent(false); static void Main(string[] args) { Task task = Task.Factory.StartNew(() => { GetDataFromServer(1); }); Task.Factory.StartNew(() => { GetDataFromServer(2); }); //Send first signal to get first set of data from server 1 and server 2 manualResetEvent.Set(); manualResetEvent.Reset(); Thread.Sleep(TimeSpan.FromSeconds(2)); //Send second signal to get second set of data from server 1 and server 2 manualResetEvent.Set(); Console.ReadLine(); /* Result * I get first data from server1 * I get first data from server2 * I get second data from server1 * I get second data from server2 * All the data collected from server2 * All the data collected from server1 */ } static void GetDataFromServer(int serverNumber) { //Calling any webservice to get data Console.WriteLine("I get first data from server" + serverNumber); manualResetEvent.WaitOne(); Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("I get second data from server" + serverNumber); manualResetEvent.WaitOne(); Console.WriteLine("All the data collected from server" + serverNumber); } }