【发布时间】:2011-01-03 16:14:01
【问题描述】:
在 .NET 中有几种方法可以执行异步线程:
System.Threading.Thread.Start()
System.Delegate.BeginInvoke()
我的问题是异步线程在这些场景中的位置是什么?在某些情况下,我想避免使用池线程,因为我正在执行的某些进程需要很长时间并且会占用池线程。
【问题讨论】:
标签: .net multithreading threadpool
在 .NET 中有几种方法可以执行异步线程:
System.Threading.Thread.Start()
System.Delegate.BeginInvoke()
我的问题是异步线程在这些场景中的位置是什么?在某些情况下,我想避免使用池线程,因为我正在执行的某些进程需要很长时间并且会占用池线程。
【问题讨论】:
标签: .net multithreading threadpool
运行从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)。
【讨论】:
当您使用 Thread.Start() 时,该线程与 ThreadPool 是分开的。当您使用 BeginInvoke 时,(IIRC) 调用被提供给线程池。与 QueueUserWorkItem 相同。
【讨论】:
在第一个场景中,他们无处可去。您正在手动创建一个新线程。在第二个示例中,如果有可用的线程池,则从线程池中抽取一个线程。您应该避免在 ASP.NET 等多线程应用程序中使用线程池中的线程进行长时间运行的操作,因为您可能会危及也用于服务请求的线程。
基本的经验法则是手动为长时间运行的操作创建线程,但很少(因为创建线程很耗时)并使用池中的线程进行多个短期操作。
【讨论】:
System.Threading.Thread.Start()
涉及创建一个不在池中的线程。
System.Delegate.BeginInvoke() 取决于实际的实现,可以是线程池、后台或前台线程。
如果您解释您的情况,我们应该能够提供更多帮助。
【讨论】: