【发布时间】: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