你好,我有這樣的代碼鎖定爲並行線程的單一訪問變量在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