0

I use Task Parallel Library and I need to synchronize access to a method but since Tasks don't necessarily create threads for asynchronous operations, I can't rely on using locks.

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

What can I use instead of lock if I want to prevent simultaneous calls from multiple tasks to Foo? I need my tasks to call Foo, one by one.


  • ContinueWith is not an option.
  • I use .NET 4.
4

2 に答える 2

6

MSDNから:

バックグラウンドで、タスクは ThreadPool のキューに入れられます。ThreadPool は、スループットを最大化するスレッド数を決定して調整するアルゴリズム (山登り法など) で強化されています。

そのため、ManualResetEvent やメモリ バリアなどの他のスレッド同期メカニズムをロックすることができます。

于 2012-07-10T15:27:07.987 に答える
2

他の回答で述べられているように、既に持っているツールを使用して必要なことを実行できます。これは、スレッド プールによって処理されます。ただし、別のメソッドに設定されている場合は、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.
    }
}

これが役立つことを願っています。

于 2012-07-10T15:26:58.903 に答える