我有一个由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完成它从头开始。
答案 0 :(得分: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();
}
}
当然有更优雅的方法,例如将WaitHandle
与WaitAll
方法一起使用(请注意,WaitAll
在大多数实现中一次限制为64个句柄,并且不适用于STA线程,如UI线程)
答案 1 :(得分:0)
您不应该从外部终止线程。 (Never kill a thread, make it commit suicide)。如果你不是很小心的话,杀死一个线程很容易破坏appdomain的状态。
您应该在线程中重写网络代码,以便在达到时间限制后超时,或者使用异步网络代码。
答案 2 :(得分:0)
通常一个线程卡在阻塞调用上(除非你有一个导致无限循环的错误)。您需要确定哪个呼叫正在阻止,并“戳”它以使其解除阻塞。可能是您的线程正在等待其中一个.NET BCL等待调用(WaitHandle.WaitOne
等),在这种情况下,您可以使用Thread.Interrupt
取消阻止它。但是,在您的情况下,管理与远程计算机的通信的API更有可能被挂起。有时你可以简单地从一个单独的线程关闭连接,这将取消阻塞挂起的方法(就像Socket
类的情况一样)。如果所有其他方法都失败了,那么你真的可能不得不回到最后一次调用Thread.Abort
的方法。请记住,如果您中止线程,可能会破坏中止源自的应用域的状态,甚至整个进程本身。 .NET 2.0中添加了许多条款,使得中止比以前更安全,但仍存在一些风险。
答案 3 :(得分:-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;
}