中止非工作线程

发布于 2024-09-28 04:49:54 字数 508 浏览 5 评论 0原文

我有一个用 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个是活动的。 soo 我正在使用 256 个线程来读取它们的值。另一件事是循环。我的循环正在工作,当所有 ipies 完成时,它从头开始。

I have a multi thread application written by c#, my max thread number is 256 and this application gets the performance counters of the computers in an Ip interval(192.168.1.0 -192.168.205.255)
it works fine and turns many times in a day. because I have to get reports.

But the problem is some times one machine keeps a thread and never finishes its work so my loop doesnt turn...

Are there any way to create threads with a countdown parameter. when I start the threads in foreach?

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

coundown parameter is the max life of each threads. This mean if a thread cant reach a machine it have to be abort. for example 60 seconds.. no not 256 machines, I meant 256 threads... there are about 5000 ip and 600 of them are alive. soo I am using 256 threads to read their values. and the other thing is loop. my loop is working as while all off the ipies finish it starts from beginning.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

筱武穆 2024-10-05 04:49:54

您无法指定线程执行的超时时间。但是,您可以尝试 加入每个线程都设置超时,如果不退出则中止它。

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();
   }
}

当然还有更优雅的方法来做到这一点,例如将 WaitHandleWaitAll 方法(请注意,WaitAll 在大多数实现中一次仅限于 64 个句柄,并且不适用于 STA 线程,就像 UI 线程一样)

You can't specify a timeout for thread execution. However, you can try to Join each thread with a timeout, and abort it if it doesn't exit.

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();
   }
}

There are of course more elegant ways to do it, like using WaitHandles with the WaitAll method (note that WaitAll is limited to 64 handles at a time on most implementations, and doesn't work on STA threads, like the UI thread)

总攻大人 2024-10-05 04:49:54

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

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

You should not terminate the thread from the outside. (Never kill a thread, make it commit suicide). Killing a thread can easily corrupt the state of an appdomain if you're not very careful.

You should rewrite the network code in the threads to either time out once the time-limit has been reached, or use asynchronous network code.

凉薄对峙 2024-10-05 04:49:54

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

Usually a thread gets stuck on a blocking call (unless of course you have a bug causing an infinite loop). You need to identify which call is blocking and "poke" it to get it to unblock. It could be that your thread is waiting inside one of the .NET BCL waiting calls (WaitHandle.WaitOne, etc.) in which case you could use Thread.Interrupt to unblock it. But, in your case it is more likely that the API managing the communication with the remote computers is hung. Sometimes you can simply close the connection from a separate thread and that will unblock the hung method (as is the case with the Socket class). If all else fails then you really might have to fall back on the method of last of calling Thread.Abort. Just keep in mind that if you abort a thread it might corrupt the state of the app domain in which the abort originated or even the entire process itself. There were a lot of provisions added in .NET 2.0 that make aborts a lot safer than they were before, but there is still some risk.

焚却相思 2024-10-05 04:49:54

你可以这样使用:

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;
}

You can use smth like this:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文