C# 中止非工作线程

C# 中止非工作线程,c#,multithreading,networking,abort,C#,Multithreading,Networking,Abort,我有一个由c#编写的多线程应用程序,我的最大线程数是256,该应用程序在Ip间隔(192.168.1.0-192.168.205.255)内获取计算机的性能计数器 它运转良好,一天转很多次。因为我必须得到报告 但问题是,有时一台机器保留一个线程,并且永远不会完成它的工作,所以我的循环不会转 有没有办法用倒计时参数创建线程。当我在foreach中启动线程时 foreach(Thread t in threads) { t.start(); -----> t.start(countdow

我有一个由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个线程来读取它们的值。另一个是循环。当所有IPIE都完成时,我的循环就开始工作。

不能为线程执行指定超时。但是,您可以尝试在每个线程上设置一个超时,如果它没有退出,就中止它

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
在大多数实现中一次只能使用64个句柄,并且不适用于STA线程,比如UI线程)

您不应该从外部终止线程。(). 如果不十分小心,杀死线程很容易损坏appdomain的状态


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

您可以像这样使用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;
}
public static T Exec(函数F,int超时,out bool完成)
{
T结果=默认值(T);
线程线程=新线程(()=>result=F());
thread.Start();
完成=线程连接(超时);
如果(!Completed)thread.Abort();
返回结果;
}

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

我不明白-您希望在这里实现什么
countdownParameter
?你说的“一机一线”是什么意思?这是如何阻止程序循环的?发布真实的代码对获得有用的反馈会有很大帮助。你有256台机器吗?还是CPU的?还是实际的“线程”?或者什么?@ ArAangangy-我不敢问,但它看起来像一个线程每IP,首先应该真正考虑把这变成一个异步设置,这样你就可以更有效地利用线程,而不会陷入你正在张贴的场景,线程花了很长时间处理所提供的对象。您以非线程方式处理线程有什么原因吗?很抱歉,让我解释一下,condown参数是每个线程的最大寿命。这意味着,如果线程无法到达机器,它必须中止。例如60秒。。不是256台机器,我是说256个线程。。。大约有5000个ip,其中600个还活着。所以我使用256个线程来读取它们的值。另一个是循环。我的循环正在工作,当所有的IPIE都完成时,它从一开始就开始。我试图用计时器控制工作时间,但它阻止了我的操作。您提供什么样的解决方案?套接字API通常有一个用于阻塞模式的超时参数/属性(例如.net套接字类上的SendTimeOut和ReceiveTimeOut),以及一种进入非阻塞(=异步)模式的方法(套接字上的阻塞属性)。“杀死线程很容易损坏appdomain的状态”对于操作系统线程来说可能是这样,但我怀疑中止托管线程是否会有这种效果。。。我只是在被中止的线程上引发了一个ThreadAbortException。我尝试了这段代码,但是所有的线程都在等待完成之前创建的线程。这不是一个有用的解决方案。