Skip to content

Instantly share code, notes, and snippets.

@dsimunic
Last active January 1, 2016 13:18
Show Gist options
  • Save dsimunic/8149872 to your computer and use it in GitHub Desktop.
Save dsimunic/8149872 to your computer and use it in GitHub Desktop.
Producer-consumer class from C#5.0 in a Nutshell, Chap 23 p.954
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace PcQueue
{
/// <summary>
/// Producer-consumer class from C#5.0 in a Nutshell, Chap 23 p.954
/// </summary>
public class ProducerConsumerQueue : IDisposable
{
BlockingCollection<Task> _taskQ = new BlockingCollection<Task>();
public ProducerConsumerQueue(int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
Task.Factory.StartNew(Consume);
}
public Task EnqueueTask(Action action, CancellationToken cancelToken = default(CancellationToken))
{
var task = new Task(action, cancelToken);
_taskQ.Add(task);
return task;
}
public Task<TResult> Enqueue<TResult>(Func<TResult> func, CancellationToken cancelToken = default(CancellationToken))
{
var task = new Task<TResult>(func, cancelToken);
_taskQ.Add(task);
return task;
}
public int Length
{
get { return _taskQ.Count; }
}
void Consume()
{
foreach (var task in _taskQ.GetConsumingEnumerable())
try {
if (!task.IsCanceled) task.RunSynchronously();
} catch (InvalidOperationException) { } // Race condition
}
public void Dispose() { _taskQ.CompleteAdding(); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment