C#等同于Java的ExecutorService.newSingleThreadExecutor(),或:如何序列mulithreaded对资源的访问序列、资源、ExecutorService、Ja

2023-09-03 06:26:43 作者:风外听竹

我有一对夫妇在我的code情况下,各个线程可以创建,由于种种原因,不应该并行完成的工作项目。我想,以确保工作能以FIFO方式进行,无论什么线程从进来。在Java中,我把工作项目上的单线程的ExecutorService ;有没有在C#中的相同呢?我拼凑在一起的东西用队列和一堆的锁(){} 块,但它会被很好能够使用一些现成的,货架和测试。

I have a couple of situations in my code where various threads can create work items that, for various reasons, shouldn't be done in parallel. I'd like to make sure the work gets done in a FIFO manner, regardless of what thread it comes in from. In Java, I'd put the work items on a single-threaded ExecutorService; is there an equivalent in C#? I've cobbled something together with a Queue and a bunch of lock(){} blocks, but it'd be nice to be able to use something off-the-shelf and tested.

更新:没有任何人有System.Threading.Tasks经验?是否有这样的事情的解决方案?我正在写一个MonoTouch的应用程序,所以谁知道如果我能甚至找不到它的反向移植版本,我能得到工作,但它会至少是值得思考未来。

Update: Does anybody have experience with System.Threading.Tasks? Does it have a solution for this sort of thing? I'm writing a Monotouch app so who knows if I could even find a backported version of it that I could get to work, but it'd at least be something to think about for the future.

更新#2 对于C#开发人员不熟悉Java库我说的,基本上我想要的东西,可以让各个线程手头宽裕的工作项目,使所有这些工作项目将在运行单个线程(其不是任何主叫线程)。

Update #2 For C# developers unfamiliar with the Java libraries I'm talking about, basically I want something that lets various threads hand off work items such that all those work items will be run on a single thread (which isn't any of the calling threads).

推荐答案

您可以使用的 ConcurrentQueue ,(如果MonoTouch的支持.NET 4?)它是线程安全的,我的认为的实施实际上是无锁。此工程pretty的好,如果你有一个长时间运行的任务(如在一个窗口服务)。

You can use ConcurrentQueue, (if monotouch supports .net 4?) it's thread safe and I think the implementation is actually lockless. This works pretty well if you have a long-running task (like in a windows service).

通常情况下,你的问题听起来像是你有多个生产跟单的消费者。

Generally, your problem sounds like you have multiple producers with a single consumer.

var work = new ConcurrentQueue<Item>();
var producer1 = Task.Factory.StartNew(() => {
    work.Enqueue(item); // or whatever your threads are doing
});
var producer2 = Task.Factory.StartNew(() => {
    work.Enqueue(item); // etc
});
var consumer = Task.Factory.StartNew(() => {
    while(running) {
        Item item = null;
        work.TryDequeue(out item);
    }
});
Task.WaitAll(producer1, producer2, consumer);

您应该使用 BlockingCollection 的,如果你有工作,有限的池项目。 这里有一个MSDN页面显示所有新的并发收集类型。

You should use BlockingCollection if you have a finite pool of work items. Here's an MSDN page showing all of the new concurrent collection types.