Многопоточность - стратегия очистки в конце программы - PullRequest
5 голосов
/ 12 марта 2010

Каков наилучший способ завершить многопоточное приложение чистым способом?
Я запускаю несколько соединений сокетов из основного потока в отдельных сокетах и ​​жду до конца моего рабочего дня в основном потоке и в настоящее время использую System.Environment.Exit(0) для его завершения.

Это приводит к необработанному исключению у одного из детей. Должен ли я остановить темы из списка? Я не хотел реализовывать какие-либо реальные остановки у детей, поэтому я задаюсь вопросом о наилучшей практике. Сокеты все аккуратно обернуты соответствующими деструкторами для выхода из системы и закрытия, но это все равно приводит к ошибкам.

Ответы [ 3 ]

4 голосов
/ 12 марта 2010

взгляните на статьи Джона Скита о многопоточности:

http://www.yoda.arachsys.com/csharp/threads/

особенно "Изящное завершение рабочих потоков":

http://www.yoda.arachsys.com/csharp/threads/shutdown.shtml

2 голосов
/ 12 марта 2010

Для созданных вручную потоков вы должны установить для свойства IsBackground значение true. В этом случае (если все ваши потоки, кроме основного) будут фоновыми, ваше приложение будет корректно закрыто после возврата из функции Main (string [] arg).

P.S. Все потоки пулов потоков являются фоновыми.

0 голосов
/ 12 марта 2010

Всякий раз, когда вы делаете длительное заблокированное ожидание (например, ожидание входящего соединения), используйте форму «Начало / Конец» метода. Затем используйте ManualResetEvent для представления условия «должен выйти». Затем заблокируйте AsyncWaitHandle и событие выхода. Это позволит вам завершить чисто.

Пример:

// exit is a ManualResetEvent
var asyncResult = socket.BeginAccept(null, null);
if(WaitHandle.WaitAny(new[] { exit, asyncResult.AsyncWaitHandle }) == 0)
   return;
var connection = socket.EndAccept(asyncResult);

И в вашем основном методе, когда вы хотите выйти:

exit.Set();
...