Убедитесь, что все темы вышли - PullRequest
6 голосов
/ 09 июня 2011

В приложении win form у меня есть массив потоков, которые запускаются так:

bool stop = false;
Thread[] threads = new Thread[10];

for (int i = 0; i < threads.Length; i++)
    threads[i] = new Thread(new ThreadStart(Job));

// How to make sure all threads have exited, when the boolean = false

void Job()
{
    while (!stop)
        // Do something
}

Теперь, если пользователь нажмет STOP, логическое значение для stop будет установлено в true, поэтому потокивыйдите из метода Job один за другим.Как я могу убедиться, что все потоки закрыты?

ПРИМЕЧАНИЕ: Мне нужна традиционная многопоточность для моего случая, а TaskLibrary не соответствует моему сценарию.

Ответы [ 3 ]

7 голосов
/ 09 июня 2011

Используйте метод Join, чтобы проверить, остановились ли все потоки.

 foreach (var t in threads)
 {
     t.Join();
 }
4 голосов
/ 09 июня 2011

Задумывались ли вы об использовании BackgroundWorkers вместо этого?Вы сказали "традиционные темы" .. Я не совсем уверен, что вы имеете в виду, поэтому я не знаю, является ли это действительным предложением или нет, но здесь это в любом случае, если Join() не решит вашу проблему

BackgroundWorker[] workers = new BackgroundWorker[10];
bool allThreadsDone = false;

// initialize BackgroundWorkers
for (int i = 0; i < 10; i++)
{
        workers[i] = new BackgroundWorker();
        workers[i].WorkerSupportsCancellation = true;
        workers[i].RunWorkerCompleted += 
            new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        workers[i].DoWork += new DoWorkEventHandler(AlgorithmsUI_DoWork);
        workers[i].RunWorkerAsync();
}

// thread entry point..DoWork is fired when RunWorkerAsync is called
void AlgorithmsUI_DoWork(object sender, DoWorkEventArgs e)
{
      while (!stop)
            // do something        
}

// this event is fired when the BGW finishes execution
private void  worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    bool threadsStillRunning = false;
    foreach (BackgroundWorker worker in workers)
    {
        if (worker.IsBusy)
        {
            threadsStillRunning = true;
            break;
        }
    }
    if (!threadsStillRunning)
        allThreadsDone = true;
} 

protected override OnFormClosing(FormClosingEventArgs e)
{
         if (!allThreadsDone)
         {
              e.Cancel = true;
              MessageaBox.Show("Threads still running!");
         }
}

Это должно предотвратить закрытие вашей формы, если какие-либо потоки все еще работают.

1 голос
/ 09 июня 2011

Я не уверен, что это то, что вам нужно, но вот простое решение, которое я использовал в .NET 3.0, чтобы убедиться, что большое, но детерминированное количество потоков завершено, прежде чем продолжить:

Global:

AutoResetEvent threadPoolComplete = new AutoResetEvent(false);
static int numThreadsToRun;

Как вы активируете темы:

numThreadsToRun = [number of threads];
[start your threads];
threadPoolComplete.WaitOne();

В конце кода каждого потока:

if (Interlocked.Decrement(ref numThreadsToRun) == 0)
{
   threadPoolComplete.Set();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...