我正在实现一个异步缓冲系统,我想要一个队列的一个消费者,以保证项目按顺序进行。消费者应定期检查队列,处理其中的所有项目,然后“休眠”一段时间。 Task.Delay()似乎非常适合这样的系统,因为与Thread.Sleep()不同,它在休眠时不会消耗线程,而且与Timer不同,如果处理队列项需要的时间超过休眠间隔,它将不会启动新线程。但是,我想知道如果任务系统正在跟踪原始任务的整个继续列表,在while循环中使用Task.Delay()是否会创建内存泄漏。作为参考,我的系统看起来像:
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();
答案 0 :(得分:6)
我正在实现一个异步缓冲系统......
我强烈建议您使用现有的。 TPL Dataflow是我的最高建议。但如果您的平台上没有该功能,那么my AsyncProducerConsumerQueue
就是一个选项。
此设置允许您的消费者只使用ReceiveAsync
/ DequeueAsync
,而且不需要Task.Delay
。
那就是说,我不相信会有像你描述的那样的内存泄漏。我实际上并没有在分析器中运行它来验证这一点。
答案 1 :(得分:3)
它不会导致内存泄漏,但是如果您处于紧密循环中,可能想要处理任务而不是等待终结器
e.g。
var t = Task.Delay(interval);
await t.ConfigureAwait(false);
t.Dispose();
但你可能不想,也不应该(见Do I need to dispose of Tasks?)