Skip to content

Instantly share code, notes, and snippets.

@valerysntx
Created December 12, 2015 21:57
Show Gist options
  • Select an option

  • Save valerysntx/e49fd064bd6faa59c123 to your computer and use it in GitHub Desktop.

Select an option

Save valerysntx/e49fd064bd6faa59c123 to your computer and use it in GitHub Desktop.
Async Produce Consume Coordinator - ProducerConsumerHub<T>
using System;
using System.Threading.Tasks;
namespace AsyncReadWritePipeline
{
public class Program
{
public class ProducerConsumerHub<T>
{
TaskCompletionSource<Empty> _consumer = new TaskCompletionSource<Empty>();
TaskCompletionSource<T> _producer = new TaskCompletionSource<T>();
//[Unsafe]
public async Task ProduceAsync(T data)
{
_producer.SetResult(data);
await _consumer.Task;
_consumer = new TaskCompletionSource<Empty>();
}
public async Task<T> ConsumeAsync()
{
var data = await _producer.Task;
_producer = new TaskCompletionSource<T>();
_consumer.SetResult(Empty.Value);
return data;
}
struct Empty {
public static readonly Empty Value = default(Empty);
}
}
public static void Main(string[] args)
{
new Program().ConsumeSomeDataAsync().Wait();
}
public async Task GetSomeDataAsync(ProducerConsumerHub<int> hub)
{
for (int i = 0; i < 10; i++)
{
await hub.ProduceAsync(i);
}
}
public async Task ConsumeSomeDataAsync()
{
var hub = new ProducerConsumerHub<int>();
var producerTask = GetSomeDataAsync(hub);
while (true)
{
var dataItemTask = hub.ConsumeAsync();
await Task.WhenAny(producerTask, dataItemTask);
if (dataItemTask.IsCompleted)
{
// process data item
Console.WriteLine(await dataItemTask);
}
if (producerTask.IsCompleted)
{
// process the end
await producerTask;
break;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment