锁定TPL的替代方案

时间:2012-07-10 15:18:29

标签: c# task-parallel-library

我使用任务并行库,我需要同步对方法的访问,但由于Tasks不一定为异步操作创建线程,所以我不能依赖于使用锁。

void Foo()
{
    lock(SyncRoot)
    {
        // Do stuff...
    }
}

如果我想阻止多个任务同时调用Foo,我可以使用什么而不是锁定?我需要我的任务一个接一个地调用Foo。


  • ContinueWith不是一个选项。
  • 我使用的是.NET 4。

2 个答案:

答案 0 :(得分:5)

来自MSDN

  

在幕后,任务排队到ThreadPool,后者已通过算法(如爬山)进行了增强,这些算法可确定并调整最大化吞吐量的线程数。

因此,您可以锁定或任何其他线程同步机制,如ManualResetEvent或Memory barrier。

答案 1 :(得分:1)

正如其他答案所述,您可以使用已有的工具做您想做的事情,这是由线程池为您处理的。但是,如果你设置了一个不同的方法,你有一个ConcurrentCollection特别是BlockingCollection,这可以用来创建你想做的生产者/消费者队列,类似下面的东西可能适用于你

public class TaskQueue : IDisposable
{
    BlockingCollection<Action> taskX = new BlockingCollection<Action>();

    public TaskQueue(int taskCount)
    {
        // Create and start new Task for each consumer.
        for (int i = 0; i < taskCount; i++)
            Task.Factory.StartNew(Consumer);  
    }

    public void Dispose() { taskX.CompleteAdding(); }

    public void EnqueueTask (Action action) { taskX.Add(Action); }

    void Consumer()
    {
        // This seq. that we are enumerating will BLOCK when no elements
        // are avalible and will end when CompleteAdding is called.
        foreach (Action action in taskX.GetConsumingEnumerable())
            action(); // Perform your task.
    }
}

我希望这会有所帮助。