使用Task.Delay()的循环是否会造成内存泄漏?

时间:2013-12-20 13:46:45

标签: c# task async-await

我正在实现一个异步缓冲系统,我想要一个队列的一个消费者,以保证项目按顺序进行。消费者应定期检查队列,处理其中的所有项目,然后“休眠”一段时间。 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();

2 个答案:

答案 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?