对于任务暂停和恢复,我可以使用ManualResetEventSlim吗?

时间:2017-05-25 07:36:07

标签: c# multithreading

我正在使用此代码进行任务恢复和暂停。我需要暂停,因为doSomething();方法不会每次都有效,例如当数据来自web api时。所以CPU不会厌倦。我在很多项目中使用它。但我不确定这是可靠的还是最好的方法。我可以问你的想法吗?

 static ManualResetEventSlim mre = new ManualResetEventSlim(false);
    static void Main(string[] args)
    {

        mre.Set();
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                mre.Wait();
                doSomething();
            }

        });

        mre.Reset();
        Console.WriteLine("Task Paused");
        Console.WriteLine("Task Will Resume After 1 Second");
        Thread.Sleep(1000);//To simulate, waiting data from Web Api etc.  for doSomething(); 
        mre.Set();

        Console.Read();
    }

1 个答案:

答案 0 :(得分:1)

您可以使用SemaphoreSlim

SemaphoreSlim _semaphore;
static void Main(string[] args)
    {
        _semaphore = new SemaphoreSlim(0);

        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                _semaphore.Wait();
                doSomething();
            }

        });

        _semaphore.Release();
        Console.WriteLine("Task Paused");
        Console.WriteLine("Task Will Resume After 1 Second");
        Thread.Sleep(1000);//To simulate, waiting data from Web Api etc.  for doSomething();    
         _semaphore.Release();
        Console.Read();
    }

信号量将永远过渡到 核心;相比之下,与ManualResetEventSlim一样,SemaphoreSlim被设计为保持用户模式 尽可能地,通常会为进程内线程通信带来更好的性能和可伸缩性  SemaphoreSlim也 提供 CurrentCount 属性,该属性提供对该计数值的访问,通常仅用于调试 目的。

<强>考虑:

与ManualResetEventSlim一样,访问SemaphoreSlim的AvailableWaitHandle属性会强制初始化 底层内核对象。这增加了后续Wait和Release调用的开销,现在需要这样做 保持WaitHandle的状态。

请注意,此属性的名称AvailableWaitHandle与WaitHandle属性的名称不同 ManualResetEventSlim。这是由于返回的WaitHandle的功能差异造成的。在等待 ManualResetEvent或ManualResetEventSlim不会更改事件的信号状态。然而, 等待信号量可能会改变信号量,因为它可以减少信号量的内部计数。因此, AvailableWaitHandle属性返回一个WaitHandle,它只表示存在计数的可能性很高 可供SemaphoreSlim消费;实际获得对相关共享资源的访问权限, 但是,必须直接等待SemaphoreSlim。

这意味着无法使用信号量进行某些同步操作 SemaphoreSlim。例如,使用Semaphore可以使用WaitHandle.WaitAll以原子方式获取 来自多个信号量的资源; SemaphoreSlim不存在该功能。