Отмена неработающей нити - PullRequest
1 голос
/ 19 октября 2010

У меня есть многопоточное приложение, написанное на c #, мой максимальный номер потока равен 256, и это приложение получает счетчики производительности компьютеров в интервале Ip (192.168.1.0 -192.168.205.255) он работает нормально и поворачивается много раз в день. потому что я должен получать отчеты.

Но проблема в том, что одна машина иногда поддерживает поток и никогда не завершает свою работу, поэтому мой цикл не вращается ...

Есть ли способ создать потоки с параметром обратного отсчета. когда я запускаю темы в foreach?

foreach(Thread t in threads)
{
   t.start(); -----> t.start(countdownParameter) etc....
}

параметр coundown - максимальный срок службы каждого потока. Это означает, что если поток не может достичь машины, он должен быть прерван. например 60 секунд .. нет не 256 машин, я имел в виду 256 потоков ... там около 5000 ip и 600 из них живы. Так я использую 256 потоков, чтобы прочитать их значения. а другая вещь это петля. Мой цикл работает так, как только все ipies заканчиваются, он начинается с начала.

Ответы [ 4 ]

0 голосов
/ 19 октября 2010

Обычно поток застревает в блокирующем вызове (если, конечно, у вас нет ошибки, вызывающей бесконечный цикл). Вам нужно определить, какой вызов блокирует, и «ткнуть» его, чтобы разблокировать. Возможно, ваш поток ожидает внутри одного из ожидающих вызовов .NET BCL (WaitHandle.WaitOne и т. Д.), В этом случае вы можете использовать Thread.Interrupt, чтобы разблокировать его. Но в вашем случае более вероятно, что API, управляющий связью с удаленными компьютерами, зависает. Иногда вы можете просто закрыть соединение из отдельного потока, и это разблокирует зависший метод (как в случае с классом Socket). Если ничего не помогает, вам, возможно, придется прибегнуть к методу last вызова Thread.Abort. Просто имейте в виду, что если вы прерываете поток, он может повредить состояние домена приложения, в котором произошел прерывание, или даже весь процесс. В .NET 2.0 было добавлено много положений, которые делают прерывания намного безопаснее, чем они были раньше, но риск все еще остается.

0 голосов
/ 19 октября 2010

Вы не должны прерывать поток снаружи. ( Никогда не убивайте поток, заставьте его совершить самоубийство ). Если вы не очень осторожны, уничтожение потока может легко повредить состояние домена приложения.

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

0 голосов
/ 19 октября 2010

Вы можете использовать что-то вроде этого:

public static T Exec<T>(Func<t> F, int Timeout, out bool Completed)
{
    T result = default(T);
    Thread thread = new Thread(() => result = F());
    thread.Start();
    Completed = thread.Join(Timeout);
    if(!Completed) thread.Abort();
    return result;
}
0 голосов
/ 19 октября 2010

Вы не можете указать тайм-аут для выполнения потока. Однако вы можете попробовать Join для каждого потока с таймаутом и прервать его, если он не завершится.

foreach(Thread t in threads)
{
   t.Start();
}

TimeSpan timeOut = TimeSpan.FromSeconds(10);
foreach(Thread t in threads)
{
   if (!t.Join(timeOut))
   {
       // Still not complete after 10 seconds, abort
       t.Abort();
   }
}

Есть, конечно, более элегантные способы сделать это, например, использовать WaitHandle s с методом WaitAll (обратите внимание, что WaitAll ограничено 64 дескрипторами одновременно в большинстве реализаций, и не работает в потоках STA, например в потоке пользовательского интерфейса)

...