如何使用任务并行库管理任务列表

时间:2015-02-12 02:03:39

标签: c# .net c#-4.0 task-parallel-library

我正在尝试管理Windows服务的任务列表,因此当我关闭服务时,我可以使用Task.WaitAll()方法停止服务关闭,直到所有剩余任务完成。例如,我有一个Run()方法执行,直到更新布尔值:

public void Run()
{
    while (runFlag)
    {
        if (MaxTasksAchieved)
        {
            System.Threading.Thread.Sleep(pollingInterval);
        }
        else
        {

            taskList.Add(Task.Factory.StartNew(() =>
            {
                // do stuff
            }));
        }
    }
}

然后在我的Stop()方法中,我有以下内容:

public void Stop()
{
    runFlag = false;

    if (taskList.Count > 0)
    {
        // wait
        Task.WaitAll(taskList.ToArray());
    }
    else
    {
        // no wait, great.
    }
}

我的问题是,如何在执行完成后优雅地将任务从列表中删除?我希望任务从列表中删除自己,所以当调用Stop()时,taskList只包含当前正在进行的任务。

4 个答案:

答案 0 :(得分:1)

为什么不使用

public void Stop()
{
   Task.WaitAll(taskList.ToArray());
 }

如果任务列表为空,则服务将立即关闭。

答案 1 :(得分:1)

由于WaitAll()等待直到所有任务完成,您可以重新初始化taskList ....

    public void Stop()
    {
        runFlag = false;

        if (taskList.Count > 0)
        {
            // wait
            Task.WaitAll(taskList.ToArray());

            taskList = new List<Task>();
        }
        else
        {
            // no wait, great.
        }
    }

答案 2 :(得分:1)

正如其他人所说,完成后可能没有必要从列表中删除任务。但是,如果必须,可以使用延续。

Task myTask = new Task(() => {
    // do stuff
});
myTask.ContinueWith(
    t => { taskList.Remove(t); }
);

答案 3 :(得分:1)

如果要从列表中删除任务,只需添加一个延续:

taskList.Add(task.ContinueWith(t = > taskList.Remove(t)));

但是您可以在所有任务上使用Task.WaitAll,因为已完成的任务已经完成。

Task.WaitAll(taskList.ToArray());

您可以通过使用任务状态

过滤列表,轻松地等待正在运行的任务
Task.WaitAll(taskList.Where(t => t.Status != TaskStatus.RanToCompletion).ToArray());