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

How to manage a list of tasks using the Task Parallel Library

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

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 仅包含当前正在进行的任务。

为什么不直接使用

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

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

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

    public void Stop()
    {
        runFlag = false;

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

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

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

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

如果您想从列表中删除任务,只需添加一个继续操作即可:

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

但是您可以简单地对所有任务使用 Task.WaitAll,因为已完成的任务已经完成。

Task.WaitAll(taskList.ToArray());

您可以轻松地只等待 运行 个任务,方法是使用任务状态

过滤列表
Task.WaitAll(taskList.Where(t => t.Status != TaskStatus.RanToCompletion).ToArray());