I am implementing an asynchronous buffer system where I want exactly one consumer of a queue to guarantee that items are processes in order. The consumer should check the queue periodically, process all items in it, and then "Sleep" for some interval. Task.Delay() seems perfect for such a system, since unlike Thread.Sleep() it won't consume a thread while sleeping and unlike Timer it won't launch a new thread if processing the queue items takes longer than the sleep interval. However, I'm wondering if using Task.Delay() in a while loop will create a memory leak if the task system is tracking the entire continuation list for the original task. For reference, my system looks like:
void EnqueueItem(Item item) {
lock (this._lock) { this._items.Add(item); }
}
async Task Consumer() {
while (true) {
await Task.Delay(interval).ConfigureAwait(false);
Item[] items = null;
lock (this._lock) {
if (this._disposed) { return; }
if (this._items.Count > 0)
{
items = this._items.ToArray();
this._items.Clear();
}
}
if (items != null) { Process(items); }
}
}
// in the constructor of the buffer
this.Consumer();
I am implementing an asynchronous buffer system...
I strongly suggest you use an existing one. TPL Dataflow is my top recommendation. But if that's not available on your platform, then my AsyncProducerConsumerQueue
is an option.
This setup allows your consumer to just use ReceiveAsync
/DequeueAsync
and no Task.Delay
is necessary.
That said, I don't believe there would be a memory leak like the one you describe. I have not actually run it in a profiler to verify this, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With