使用Task.ContinueWith创建执行队列?

时间:2011-07-21 17:08:17

标签: c# task task-queue

我想在后台执行几个动作,但它们必须一个接一个地同步执行。

我想知道使用Task.ContinueWith方法实现这一点是否是个好主意。你有没有预见到这个问题?

我的代码看起来像这样:

private object syncRoot =new object();
private Task latestTask;

public void EnqueueAction(System.Action action)
{
    lock (syncRoot)
    {
        if (latestTask == null)
            latestTask = Task.Factory.StartNew(action);
        else
            latestTask = latestTask.ContinueWith(tsk => action());
    }
}

3 个答案:

答案 0 :(得分:7)

这有一个缺陷,我最近发现自己,因为我也在使用这种确保任务顺序执行的方法。

在我的应用程序中,我有数千个这些迷你队列的实例,并很快发现我有内存问题。由于这些队列经常处于空闲状态,因此我长时间保留最后完成的任务对象并阻止垃圾回收。由于上次完成的任务的结果对象通常超过85,000字节,因此它被分配给大对象堆(在垃圾收集期间不执行压缩)。这导致LOH碎裂,并且该过程的尺寸不断增大。

作为避免这种情况的黑客攻击,您可以在锁定中的真实任务之后立即安排无操作任务。对于一个真正的解决方案,我需要采用另一种控制调度的方法。

答案 1 :(得分:5)

这应该按照设计工作(如果相应的任务已经完成,则使用TPL将立即安排继续的事实。)

在这种情况下,我个人会使用一个使用并发队列(ConcurrentQueue)的专用线程来绘制任务 - 这更明确但更容易解析代码,特别是如果你想找出ie目前有多少任务排队等等。

答案 2 :(得分:0)

我使用了这个代码段,似乎让它按设计运行。 在我的情况下,实例的数量不会达到数千,而是以一位数表示。 尽管如此,到目前为止还没有问题。

我会对ConcurrentQueue示例感兴趣,如果有的话?

由于