2012-01-28 38 views
0

你好,我有这样的代码锁定为并行线程的单一访问变量在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)被激活,以便代码执行,直到没有更多项目被添加到队列中。我希望你能理解这个问题。 换句话说,我需要这个动作无限地运行,直到我告诉它停止。 有什么建议吗?

+1

count只在'Enumerate.Range'中占用一次,所以它不会观察到后续在'ForEach'中的代码所做的更改。也许如果你告诉我们你想要做什么,我们可以提供更好的解决方案。我无法清楚地看到为什么要使用阻塞收集和任务并锁定在一起。 – oleksii 2012-01-28 21:15:06

+0

很难想象你想在这里做什么。如果存在,代码将始终生成一个项目的列表。也就是说,'Enumerable.Rang(1,queue.Count).ToList()'创建一个包含队列内容的新列表。该列表从不更新。另外,如果可能有很多项目,您可能会考虑使用除队列之外的其他项目。 'queue.contains'是一个O(N)操作,所以这将在泡泡排序的情况下执行。 – 2012-01-28 21:52:57

回答

1

我很抱歉地说,但我不能明白你写类似的东西,没有进一步的解释:(

动机以任何方式对你有用下面的代码呢?因为我不认为它是:P

 int n = 2; 

     Task[] producers = Enumerable.Range(1, 3).Select(_ => 
      Task.Factory.StartNew(() => 
       { 
        while (queue.Count < n) 
        { 
         lock (queue) 
         { 
          if (!queue.Contains(n)) 
          { 
           Console.WriteLine("Thread" + Task. CurrentId); 
           queue.Add(n); 

           Interlocked.Increment(ref n); 
          } 
         } 

         Thread.Sleep(100); 
        } 
       })) 
      .ToArray(); 

我的意思是,它只会继续下去It's喜欢的只是增加数以列表的reeeeeeaaallllyyy奇怪的方式

请解释一下你的目标,我们也许可以。帮助你。

+0

哈哈我想是的,这可以工作,我会测试它,当我回家,我很难用简单的方式来解释问题,我会稍后回来:P thanx – themis 2012-01-28 23:02:47

+0

嗨@Johan,我会说这个贡献不是真的是一个有益的,建设性的和解决问题的答案。请记住,您不只是回答一个人,而是永远将您的贡献留在问答中。如果问题的作者不能很好地表达自己的意思,你仍然可以通过在评论中提问或编辑问题来帮助他。 – 2012-01-28 23:35:33

+0

@ achitaka-san,那是对的。这似乎是一个意见问题。我想我无法确定这种类型,如果我所制作的贡献,但看起来他们很高兴与答案无论如何。 – Johan 2012-01-29 01:05:11

1

我明白了,您需要的是随.NET 4.0一起提供的BlockingCollection。 它允许实施生产者 - 消费者模式。

多个线程或任务可以同时向集合中添加项目。多个消费者可以同时移除项目,并且如果该收集变空,则消费线程将阻塞并等待,直到生产者添加项目。一遍又一遍... ...

...直到一个特殊的方法将被生产者称为识别结束,说消费者“嘿,停止等待 - 没有什么会再来的!”。

我不是发布代码示例,因为有一些在给定的链接。你可以找到更多,如果你只是谷歌生产者 - 消费者模式和/或BlockingCollection

+0

thanx achitaka-san,我认为你是对的,我需要了解生产者 - 消费者模式才能做到这一点。 – themis 2012-01-29 01:51:30