Dav*_*les 18 .net c# concurrency multithreading
我的代码中有几种情况,各种线程可以创建工作项,由于各种原因,不应该并行完成.我想确保工作以FIFO方式完成,无论它来自哪个线程.在Java中,我将工作项放在单线程上ExecutorService; 在C#中是否有等价物?我用Queue一堆和一些lock(){}块拼凑了一些东西,但是能够使用现成的和经过测试的东西会很好.
更新:有没有人有System.Threading.Tasks的经验?它有这种解决方案吗?我正在写一个MonoTouch的应用程序,所以谁知道,如果我甚至可以找到它的反向移植版本,我能得到工作,但它会至少是值得思考的未来.
更新#2对于C#开发人员不熟悉我说的Java库,基本上我想要的东西,可以让不同的线程交班工作项目等,所有这些工作项目将在单个线程中运行(这不是任何的调用线程).
更新,6/201:如果我现在正在构建一个类似的系统,我可能会根据Matt Craig的回答使用Reactive Extensions.我要离开扎卡里·耶茨的回答公认的一个,不过,因为如果你在思考的Rx你可能甚至不会问这个问题,我认为是比较容易bodge到预先的Rx程序.ConcurrentQueue
更新:要解决有关浪费资源的评论(如果您不使用 Rx),您可以使用 a BlockingCollection(如果您使用默认构造函数,它会包装 a ConcurrentQueue)并调用.GetConsumingEnumerable()。CancellationToken如果工作长时间运行,就会出现过载。请参阅下面的示例。
您可以使用ConcurrentQueue,(如果 monotouch 支持 .net 4?)它是线程安全的,我认为该实现实际上是无锁的。如果您有一个长时间运行的任务(例如在 Windows 服务中),这非常有效。
一般来说,您的问题听起来像是有多个生产者和一个消费者。
var work = new BlockingCollection<Item>();
var producer1 = Task.Factory.StartNew(() => {
work.TryAdd(item); // or whatever your threads are doing
});
var producer2 = Task.Factory.StartNew(() => {
work.TryAdd(item); // etc
});
var consumer = Task.Factory.StartNew(() => {
foreach (var item in work.GetConsumingEnumerable()) {
// do the work
}
});
Task.WaitAll(producer1, producer2, consumer);
Run Code Online (Sandbox Code Playgroud)
如果您的工作项池有限,则 应该使用BlockingCollection 。这是一个 MSDN 页面,显示了所有新的并发集合类型。
| 归档时间: |
|
| 查看次数: |
12527 次 |
| 最近记录: |