1

我有一个由 c# 编写的多线程应用程序,我的最大线程数是 256,并且该应用程序在 Ip 间隔(192.168.1.0 -192.168.205.255)内获取计算机的性能计数器,它工作正常,并且一天内转了很多次。因为我必须得到报告。

但问题是有时一台机器保持一个线程并且永远不会完成它的工作,所以我的循环不会转动......

有没有办法用倒计时参数创建线程。当我在 foreach 中启动线程时?

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

countdown 参数是每个线程的最大寿命。这意味着如果线程无法到达机器,则必须中止。例如60秒..不是256台机器,我的意思是256个线程......大约有5000个ip,其中600个还活着。所以我正在使用 256 个线程来读取它们的值。另一件事是循环。我的循环正在工作,因为所有 ipies 都完成了它从头开始。

4

4 回答 4

0

通常一个线程会被阻塞调用(当然除非你有一个导致无限循环的错误)。您需要确定哪个呼叫正在阻塞并“戳”它以使其解除阻塞。可能是您的线程在其中一个 .NET BCL 等待调用(WaitHandle.WaitOne等)中等待,在这种情况下,您可以使用Thread.Interrupt它来解除阻塞。但是,在您的情况下,管理与远程计算机通信的 API 更有可能挂起。有时您可以简单地从单独的线程关闭连接,这将解除挂起方法的阻塞(就像Socket类的情况一样)。如果所有其他方法都失败了,那么你真的可能不得不依赖 last of call 的方法Thread.Abort。请记住,如果您中止一个线程,它可能破坏发起中止的应用程序域的状态,甚至破坏整个进程本身。.NET 2.0 中添加了许多条款,使中止比以前更安全,但仍然存在一些风险。

于 2010-10-19T12:52:05.707 回答
0

您不应该从外部终止线程。(永远不要杀死线程,让它自杀)。如果你不是很小心,杀死一个线程很容易破坏应用程序域的状态。

您应该重写线程中的网络代码,以便在达到时间限制后超时,或者使用异步网络代码。

于 2010-10-19T07:35:14.703 回答
0

您不能为线程执行指定超时。但是,您可以尝试对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();
   }
}

当然还有更优雅的方法可以做到这一点,例如将WaitHandles 与WaitAll方法一起使用(请注意,WaitAll在大多数实现中一次限制为 64 个句柄,并且不适用于 STA 线程,如 UI 线程)

于 2010-10-18T23:16:24.607 回答
-1

你可以像这样使用 smth:

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;
}
于 2010-10-19T08:20:17.933 回答