2010-10-18 44 views
1

我有一个由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个线程来读取它们的值。另一件事是循环。我的循环正在工作,而所有的客户端完成它从一开始就开始。

+0

我不明白 - 你想要'countdownParameter'在这里实现什么? “一台机器保持线程”是什么意思?这是如何阻止你的程序循环?发布真实的代码对于获得有用的反馈会有很大的帮助。 – 2010-10-18 23:13:06

+0

你有256 *机器*?还是CPU的?还是实际的“线程”?或者是什么? – Arafangion 2010-10-18 23:21:24

+0

@Arafangion - 我不敢问,但它看起来像一个线程,每个IP,乍一看 – 2010-10-18 23:22:55

回答

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 s的的WaitAll方法(注意:WaitAll在大多数实现时间限制为64个手柄,并且在STA线程不工作,像UI线程)

+0

我试过这段代码,但所有的线程都在等待完成之前创建的线程。这并不是有用的解决方案。 – Rapunzo 2010-10-21 13:32:39

0

你不应该从外部终止线程。 (Never kill a thread, make it commit suicide)。如果你不是非常小心的话,杀死一个线程很容易破坏一个appdomain的状态。

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

+0

我试图用计时器控制工作时间,但它阻止了我的操作。你提供什么样的解决方案? – Rapunzo 2010-10-19 07:38:46

+0

套接字API通常具有阻塞模式的TimeOut参数/属性(例如.net Socked类上的SendTimeOut和ReceiveTimeOut),以及进入非阻塞(=异步)模式(Socket上的阻塞属性)的方式。 – CodesInChaos 2010-10-19 07:44:43

+0

“杀死一个线程可能很容易破坏一个appdomain的状态”也许这对操作系统线程是真的,但我怀疑中止一个托管线程会产生这种效果......我只是在中止的线程上引发一个ThreadAbortException。 – 2010-10-21 14:58:44

-1

您可以使用水木清华这样的:

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

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