【问题标题】:Using Interlocked.Decrement inside If condition, could it cause any Concurrency Issue?在 If 条件中使用 Interlocked.Decrement 会导致任何并发问题吗?
【发布时间】:2017-08-16 03:51:22
【问题描述】:

我正在创建一个自定义的 CountdownWaitHandle 类,它具有以下方法:

public void Signal()
{
    if (Interlocked.Decrement(ref threadsInstances) <= 0)
    {
        mre.Set();
    }
}

mre 是 ManualResetEvent 类的一个实例,我使用这个类来阻塞当前线程并等待所有线程完成他的工作,每个线程在完成他的工作或发生异常时调用 Signal() 方法。

所以我的问题是 Interlock.Decrement 和 condition( 或者我必须对 if 条件和使用 lock 语句如果像上面的例子那样使用 body 而不是 Interlock:

 lock(_lock)
   {
        if (--threadsInstances <= 0)
        {
            mre.Set();
        }   
   }

注意:我使用的是 3.5 网络。

完整代码:

 public class CountdownWaitHandle : WaitHandle
    {    
        private int threadsInstances = 0;            
        private ManualResetEvent mre;    
        private readonly object threadsyncAccess = new object();

        public CountdownWaitHandle(int initialCount)
        {
            threadsInstances = initialCount;
            mre = new ManualResetEvent(false);
        }

        public void AddCount()
        {
            Interlocked.Increment(ref threadsInstances);
        }

        public void Signal()
        {
            if (Interlocked.Decrement(ref threadsInstances) <= 0)
            {
               mre.Set();
            }
        }

        public override bool WaitOne()
        {
            return mre.WaitOne();
        }   

    }

在这个例子中。
我将使用我的自定义 CountdownEvent 类来下载一个大 使用任何云站点的块的文件。因此,每个块在完成下载他的范围字节后都会释放资源或移动到另一个流。

public static void Main(String[] args)
   {          

        CountdownWaitHandle customCountDown = new CountdownWaitHandle(0)               

                    while (i < 100)
                    {

                        SpecificWork work1  = new SpecificWork (startPosition, endPosition, customCountDown);
                        customCountDown.AddCount();                                                       
                        ThreadPool.QueueUserWorkItem(PerformTask, work1); //  after finish download it invokes to Signal method. 
                    }
                    customCountDown.WaitOne();
                }

【问题讨论】:

  • 要回答这个问题,我们必须看到代码的“其他”部分,Wait() 部分和Interlocked.Increment
  • 我无法使用 CountdownEvent.cs(.net 4),因为我使用的是 .net 3.5。
  • "if (Interlocked.Decrement(ref threadsInstances)

标签: c# multithreading thread-safety .net-3.5


【解决方案1】:

Interlocked.Decrement 将按此示例中的预期工作,假设您调用 Interlocked.Increment 将计数提高到零以上。

当然,使用CountdownEvent 会比构建自己的同步对象更好。

【讨论】:

    猜你喜欢
    • 2018-12-21
    • 2013-04-04
    • 2023-03-28
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多