Здравствуйте, ILS, Вы писали:
ILS>Добрый день.
ILS>Недавно начал изучение .NET и вот взялся за многопоточное приложение. Пишу программу, которая по команде пользователя запускает на выполнение некоторое количество потоков (ограниченное сверху). По нажатию кнопки взводится флажок и все запущенные потоки прекращают свою работу. Если флажок не появляется, то поток просто доделывает свое дело и также прекращает работу.
ILS>Проблема появляется, когда во время работы потоков пользователь закрывает окно. Всё виснет.
ILS>}
ILS>[/c#]
ILS>На закрытие формы я пробегаю по массиву и каждый поток останавливаю
ILS>ILS>private void FrmLogCollector_FormClosing(object sender, FormClosingEventArgs e)
ILS>{
ILS> if (isRunning)
ILS> {
ILS> isRunning = false; //сбрасываем флажок
ILS> foreach (Thread t in threads)
ILS> {
ILS> t.Abort();
ILS> //t.Join(); //если убрать коммент, то виснет еще тут. если коммент стоит, то виснет после выхода из этой функции
ILS> }
ILS> }
ILS>}
ILS>
ILS>Если не пробегать по массиву, то падает при попытке обратиться к Invoke.
Во-первых,
Метод Abort, по-моему, просто инициирует закрытие потока, но он не ждёт, пока закроется поток, а сразу возвращается в метод его вызвавший. Попробуй в этом обработчике события дождаться завершения всех потоков (смотри в сторону WaitHangle) и только потом выходить из метода (e.Cancel = false ? Так?)
ILS>ILS>private void ThreadDone(int index) //функция вызывается когда, когда поток завершает работу
ILS>{
ILS> SafeThreadDoneDelegate d = new SafeThreadDoneDelegate(SafeThreadDone);
ILS> Invoke(d, new object[] { index });
ILS> threads.Remove(Thread.CurrentThread);
ILS> curThreadCount--;
ILS>}
ILS>
ILS>Что делать, как быть?
Во-вторых,
К тому же, как видно из кода, у тебя переменная управляющая выходом из цикла curThreadCount открыта для свободного конкурентного доступа разных потоков одновременно. Это есть грубейшая ошибка, которая, скорее всего, и является источником проблемы. Обволоки её в lock() !