你好,我有这样的代码锁定为并行线程的单一访问变量在C#
var queue = new BlockingCollection<int>();
queue.Add(0);
var producers = Enumerable.Range(1, 3)
.Select(_ => Task.Factory.StartNew(()=>
{
Enumerable.Range(1, queue.Count)
.ToList().ForEach(i =>
{
lock (queue)
{
if (!queue.Contains(i))
{
Console.WriteLine("Thread" + Task.CurrentId.ToString());
queue.Add(i);
}
}
Thread.Sleep(100);
});
}))
.ToArray();
Task.WaitAll(producers);
queue.CompleteAdding();
foreach (var item in queue.GetConsumingEnumerable())
{
Console.WriteLine(item.ToString());
}
但我每次都需要一个单独的线程的广告东西的queue.Add(i)本 Enumerable.Range( 1,queue.Count)被激活,以便代码执行,直到没有更多项目被添加到队列中。我希望你能理解这个问题。 换句话说,我需要这个动作无限地运行,直到我告诉它停止。 有什么建议吗?
count只在'Enumerate.Range'中占用一次,所以它不会观察到后续在'ForEach'中的代码所做的更改。也许如果你告诉我们你想要做什么,我们可以提供更好的解决方案。我无法清楚地看到为什么要使用阻塞收集和任务并锁定在一起。 – oleksii 2012-01-28 21:15:06
很难想象你想在这里做什么。如果存在,代码将始终生成一个项目的列表。也就是说,'Enumerable.Rang(1,queue.Count).ToList()'创建一个包含队列内容的新列表。该列表从不更新。另外,如果可能有很多项目,您可能会考虑使用除队列之外的其他项目。 'queue.contains'是一个O(N)操作,所以这将在泡泡排序的情况下执行。 – 2012-01-28 21:52:57