Завершение работы потоков
От: ILS Россия  
Дата: 10.03.06 07:40
Оценка:
Добрый день.

Недавно начал изучение .NET и вот взялся за многопоточное приложение. Пишу программу, которая по команде пользователя запускает на выполнение некоторое количество потоков (ограниченное сверху). По нажатию кнопки взводится флажок и все запущенные потоки прекращают свою работу. Если флажок не появляется, то поток просто доделывает свое дело и также прекращает работу.
Проблема появляется, когда во время работы потоков пользователь закрывает окно. Всё виснет.

При запуске потока я его запоминаю в массиве

public ArrayList threads;
...

private void btnStart_Click(object sender, EventArgs e)
{
  foreach (int i in checkedIndices)
  {                
    MyThreadClass clc = new MyThreadClass(paramString1,
      new CallbackFunction(ThreadStart), //функция для обновления инфы формы при запуске потока
      new CallbackFunction(ThreadDone)); //функция для обновления инфы формы при завершении работы потока (там мы удаляем поток из массива и уменьшаем число запущенных)
                
    Thread t = new Thread(new ThreadStart(clc.CollectComputerLog));
    t.IsBackground = true;                
    t.Start();
    threads.Add(t);

    while ((curThreadCount >= maxThreadCount) & (isRunning)) //проверка на достижение максимального количества запущенных потоков
      UpdateTotalInfo();
             
    if (!isRunning) //тот самый флажок
      break;
}

На закрытие формы я пробегаю по массиву и каждый поток останавливаю
private void FrmLogCollector_FormClosing(object sender, FormClosingEventArgs e)
{
  if (isRunning)
  {
    isRunning = false; //сбрасываем флажок
    foreach (Thread t in threads)
    {
      t.Abort();
      //t.Join(); //если убрать коммент, то виснет еще тут. если коммент стоит, то виснет после выхода из этой функции
    }
  }    
}

Если не пробегать по массиву, то падает при попытке обратиться к Invoke.
private void ThreadDone(int index) //функция вызывается когда, когда поток завершает работу
{
  SafeThreadDoneDelegate d = new SafeThreadDoneDelegate(SafeThreadDone);
  Invoke(d, new object[] { index });

  threads.Remove(Thread.CurrentThread);
  curThreadCount--;
}

Что делать, как быть?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.