Joh*_*eer 8 c# locking task-parallel-library
我正在尝试实现Parallel.ForEach模式并跟踪进度,但我遗漏了一些有关锁定的内容.以下示例计数为1000时threadCount = 1,但不是threadCount> 1. 当正确的方法是什么时候?
class Program
{
static void Main()
{
var progress = new Progress();
var ids = Enumerable.Range(1, 10000);
var threadCount = 2;
Parallel.ForEach(ids, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, id => { progress.CurrentCount++; });
Console.WriteLine("Threads: {0}, Count: {1}", threadCount, progress.CurrentCount);
Console.ReadKey();
}
}
internal class Progress
{
private Object _lock = new Object();
private int _currentCount;
public int CurrentCount
{
get
{
lock (_lock)
{
return _currentCount;
}
}
set
{
lock (_lock)
{
_currentCount = value;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
svi*_*ick 19
count++从多个线程(共享count变量)调用类似事件的常见问题是这一系列事件可能发生:
count.count.count.count.这样,线程A写入的值被线程B覆盖,因此该值实际上只增加一次.
您的代码会在操作1,2(get)和5,6 ()之间添加锁定set,但这对于阻止有问题的事件序列没有任何作用.
你需要做的是锁定整个操作,这样当线程A递增值时,线程B根本无法访问它:
lock (progressLock)
{
progress.CurrentCount++;
}
Run Code Online (Sandbox Code Playgroud)
如果您知道只需要递增,则可以创建一个Progress封装它的方法.