哪些线程存在于.NET ThreadPool中?

时间:2011-01-03 16:14:02

标签: .net multithreading threadpool

在.NET中有几种方法可以执行异步线程:

System.Threading.Thread.Start()

System.Delegate.BeginInvoke()

我的问题是异步线程在每种情况下都存在于何处?我想在某些情况下避免使用池化线程,因为我正在执行的某些进程需要很长时间,并且会强制使用池化线程。

4 个答案:

答案 0 :(得分:4)

运行从Delegate.BeginInvoke调用的代码的线程与从ThreadPool类访问的池存在于同一个池中。创建自己的Thread对象就是这样:创建一个新的(非池化)线程。

以下是一种快速验证方法:创建一个新的Windows窗体应用程序并在窗体上放置两个按钮。包括类似以下代码的内容:

private void ThreadStartButton_Click(object sender, EventArgs e)
{
    ThreadPool.SetMaxThreads(4, 4);
    for (int i = 0; i < 8; ++i)
    {
        Thread t = new Thread(ShowMessageBox);
        t.Start();
    }
}

private void DelegateBeginInvokeButton_Click(object sender, EventArgs e)
{
    ThreadPool.SetMaxThreads(4, 4);
    for (int i = 0; i < 8; ++i)
    {
        Action action = ShowMessageBox;
        action.BeginInvoke(action.EndInvoke, null);
    }
}

private void ShowMessageBox()
{
    int threadId = Thread.CurrentThread.ManagedThreadId;
    MessageBox.Show(threadId.ToString());
}

当您单击第一个按钮(其处理程序创建新Thread个对象的按钮)时,您应该会看到一次弹出8个对话框。当您单击第二个(调用BeginInvoke)时,您应该会看到最多弹出4个对话框。前四次通过单击“确定”关闭其中一个,将弹出另一个对话框(具有相同的线程ID),因为关闭的对话框的线程将返回到池中。

答案 1 :(得分:3)

当您使用Thread.Start()时,该线程与ThreadPool分开。当您使用BeginInvoke(IIRC)时,将调用线程池。与QueueUserWorkItem相同。

答案 2 :(得分:2)

在第一个场景中,他们无处可去。您正在手动创建新线程。在第二个示例中,如果有一个线程可用,则从线程池中抽取一个线程。在长时间运行的操作中,应该避免在大量多线程应用程序(如ASP.NET)中使用线程池中的线程,因为这可能会危及用于服务请求的线程。

基本的经验法则是为长时间运行的操作手动创建线程,但很少(因为创建线程非常耗时)并使用池中的线程进行多次短期操作。

答案 3 :(得分:0)

System.Threading.Thread.Start()

涉及创建不在池中的线​​程。

System.Delegate.BeginInvoke()取决于实际的实现,可以是线程池,后台或前台线程。

如果你解释你的情况,我们应该能够提供更多帮助。