我想在后台执行几个动作,但它们必须一个接一个地同步执行。
我想知道使用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());
}
}
答案 0 :(得分:7)
这有一个缺陷,我最近发现自己,因为我也在使用这种确保任务顺序执行的方法。
在我的应用程序中,我有数千个这些迷你队列的实例,并很快发现我有内存问题。由于这些队列经常处于空闲状态,因此我长时间保留最后完成的任务对象并阻止垃圾回收。由于上次完成的任务的结果对象通常超过85,000字节,因此它被分配给大对象堆(在垃圾收集期间不执行压缩)。这导致LOH碎裂,并且该过程的尺寸不断增大。
作为避免这种情况的黑客攻击,您可以在锁定中的真实任务之后立即安排无操作任务。对于一个真正的解决方案,我需要采用另一种控制调度的方法。
答案 1 :(得分:5)
这应该按照设计工作(如果相应的任务已经完成,则使用TPL将立即安排继续的事实。)
在这种情况下,我个人会使用一个使用并发队列(ConcurrentQueue
)的专用线程来绘制任务 - 这更明确但更容易解析代码,特别是如果你想找出ie目前有多少任务排队等等。
答案 2 :(得分:0)
我使用了这个代码段,似乎让它按设计运行。 在我的情况下,实例的数量不会达到数千,而是以一位数表示。 尽管如此,到目前为止还没有问题。
我会对ConcurrentQueue示例感兴趣,如果有的话?
由于