2011-01-03 2 views
0

Есть несколько способов выполнения асинхронных потоков в .NET:Какие темы живут в .NET ThreadPool?

System.Threading.Thread.Start()

System.Delegate.BeginInvoke()

Мой вопрос, где делать асинхронные темы жить в каждом из этих сценариев? Я хочу, в некоторых случаях, избегать использования пула потоков, потому что некоторые процессы, которые я выполняю, занимают много времени и будут связаны с объединенным потоком.

ответ

4

Темы, которые запускают код с 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-х диалогов. Первые четыре раза вы удаляете один из них, нажимая «ОК», появляется другое диалоговое окно (с тем же идентификатором потока), когда поток закрытого диалога возвращается в пул.

+0

Спасибо, что показали мне доказательство концепции! – Achilles

2

В первом сценарии они живут в никуда. Вы вручную создаете новый поток. Во втором примере поток вытягивается из пула потоков, если есть один доступный. Вам следует избегать использования потоков из пула потоков в сильно многопоточных приложениях, таких как ASP.NET, для длительных операций, поскольку вы можете подвергать опасности потоки, которые также используются для обслуживания запросов.

Основное правило состоит в том, чтобы вручную создавать потоки для длительных операций, но немногие из них (поскольку создание потока занимает много времени) и используют потоки из пула для нескольких коротких операций.

3

Когда вы используете Thread.Start(), этот поток отдельно от ThreadPool. Когда вы используете BeginInvoke, (IIRC), вызов передается в threadpool. То же самое с QueueUserWorkItem.

+0

У вас есть документ MSDN, на который вы ссылаетесь? Кажется, это ответ. – Achilles

+0

http://shiman.wordpress.com/2008/09/10/c-net-delegates-asynchronous-invocation-begininvoke-method/ – KeithS

0
System.Threading.Thread.Start() 

Привлекает создание нити, которая не находится в бассейне.

System.Delegate.BeginInvoke() будет зависеть от фактической реализации, которая может быть пулом потоков, фоном или передним потоком.

Если вы объясните свое дело, мы сможем помочь вам больше.

Смежные вопросы