为什么我的线程在完成后退出需要这么长时间?

时间:2015-10-26 14:06:54

标签: c# multithreading winforms task-parallel-library

我有一个问题(也许这不是一个问题)我创建一个线程,它做它的工作,然后我完成并且工作线程(我创建了任务)退出。在我看来,我看到所有内容都已完成,我创建的新主题应该已经退出。但由于某种原因,线程在函数完成后实际上并没有退出几秒钟(大约5-8秒)。我可以通过观察输出窗口来判断......

  

线程'threadTaskWorker16'(0xdd8c)已退出,代码为0(0x0)。

以下是我创建新主题的方法......

public bool CreateNewTask()
{
    Task<TaskInfo> taskWork = Task.Factory
        .StartNew(() => threadTaskWorker(taskParams),
        CancellationToken.None,
        TaskCreationOptions.None,
        TaskScheduler.Default)
        .ContinueWith(task => threadTaskComplete(task.Result));
}

private TaskInfo threadTaskWorker(TaskInfo taskParams)
{
    Thread.CurrentThread.Name = "threadTaskWorker" + Thread.CurrentThread.ManagedThreadId;
    Debug.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " has started it's long and exhausting process that would have hung the GUI out to dry...");
    for (int i = 0; i < 50; i++)
    {
        Thread.Sleep(3000);
    }
    Debug.WriteLine("Thread has completed it's work.");
}

private TaskInfo threadTaskComplete(TaskInfo taskParams)
{
    Debug.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " has been destroyed.");
}

所以我的问题是,为什么在自定义函数完成后实际退出线程需要这么长时间?我正在考虑以某种方式在我的函数结束时杀死线程,但似乎我会以错误的方式解决它。有没有办法让线程更快退出?

第二个问题,有没有办法解雇事件,所以我知道线程何时实际退出(就像我在输出窗口中看到的那样)?

1 个答案:

答案 0 :(得分:3)

您正在看到ThreadPool的效果。由于创建新线程的计算成本很高,因此任务将保留一个“池”线程,如果它们不在使用中,则将它们重用于多个任务。只有在Pool看到它有额外的未使用线程之后才会实际杀死线程,在输出窗口中显示该消息。

任务完成后,应立即调用threadTaskDestroyed,不需要任何类型的事件。如果您真的想要更多控件,请查看一些同步对象,例如MutexAutoResetEvent。如果您正在使用任务,则不必担心管理线程,这些都是为您处理的,并且在大多数情况下“做正确的事情”。

有关详细信息,请参阅此MSDN文章https://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx

BTW,从不杀死一个帖子。你会把事情处于非常不可预测的状态。 http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation