Reputation: 7345
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.
Upvotes: 0
Views: 2711
Reputation: 23833
As has been stated in other answers, you can do what you desire with the tools you have already, and this is handled for you by the thread pool. However, if you are set on a different method have you looked at a ConcurrentCollection
specifically a BlockingCollection
this can be used to create producer/consumer queue that does what you want, something like the following might work for you
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.
}
}
I hope this helps.
Upvotes: 2
Reputation: 7411
From MSDN:
Behind the scenes, tasks are queued to the ThreadPool, which has been enhanced with algorithms (like hill-climbing) that determine and adjust to the number of threads that maximizes throughput.
So you can lock or any other threading synchronisation mechanism like ManualResetEvent or Memory barriers.
Upvotes: 6