Потоки, которые запускают код, вызванный из Delegate.BeginInvoke
, существуют в том же пуле, что и те, к которым обращаются из класса ThreadPool
. Создание собственного Thread
объекта делает именно это: создает новый (не объединенный в пул) поток.
Вот быстрый способ убедиться в этом: создайте новое приложение Windows Forms и поместите в форму две кнопки. Включите что-то вроде следующего кода:
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 диалоговых окон. Первые четыре раза, когда вы закрываете один из них, нажимая «ОК», должен появиться другой диалог (с тем же идентификатором потока), когда поток закрытого диалога возвращается в пул.