C# equivalent for Java ExecutorService.newSingleThreadExecutor(), or: how to serialize mulithreaded access to a resource

Update: To address the comments on wasting resources (and if you're not using Rx), you can use a BlockingCollection (if you use the default constructor, it wraps a ConcurrentQueue) and just call .GetConsumingEnumerable(). There's an overload that takes a CancellationToken if the work is long-running. See the example below.


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 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);

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.