如果未返回,则在间隔后终止一个线程

时间:2010-12-21 16:58:59

标签: c# .net multithreading intervals terminate

我有一个线程可以从网络或串口获取一些数据。如果在5秒内没有收到数据,则线程必须终止(或返回false)。

换句话说,如果运行线程的时间超过5秒,则必须停止。

我用C#编写,但任何.NET语言都可以。

6 个答案:

答案 0 :(得分:8)

有两种方法:

1。封装超时

从网络或串行端口读取数据的线程可以测量从启动时间开始经过的时间,并等待数据不超过剩余时间。网络通信API通常提供为操作指定超时的方法。因此,通过执行简单的DateTime算法,您可以在工作线程中封装超时管理。

2。外部超时

使用另一个线程(或者如果可行的话,在主线程中执行)等待工作线程在特定时间限制内完成,如果没有,则中止它。像这样:

// start the worker thread
...

// give it no more than 5 seconds to execute
if (!workerThread.Join(new TimeSpan(0, 0, 5)))
{    
    workerThread.Abort();
}

建议:我坚持使用第一个解决方案,因为它可以实现更清晰,更易于维护的设计。但是,在某些情况下,可能需要提供“硬”的方法。中止这种工作线程。

答案 1 :(得分:4)

这两种机制都允许您在读取时指定超时。例如,您可以在执行读取之前将NetworkStream.ReadTimeout设置为5000。您应该可以为串行端口执行类似的操作。

超时的读数将从Stream.Read()返回0 - 这就是你如何确定实际发生超时的方法。

请注意,从.NET 2.0开始,不推荐使用Thread.Abort()来解决它可能导致的一些严重问题。理论上你可以使用Thread.Interrupt(),但是当线程在非托管代码(包括I / O)中被阻塞时,这不会做任何事情。使用读取超时是解决此问题的正确方法。

答案 2 :(得分:3)

如果使用托管代码阻止该线程,则可以使用Thread.Abort中止执行。如果您使用第三方代码或COM互操作,则无法终止线程执行。唯一的方法是将Thread.isBackroundThread设置为true,然后终止Process ...

答案 3 :(得分:2)

您提到您正在阅读“网络”。如果您使用NetworkStream进行阅读,则可以将ReadTimeout指定为5000(以毫秒为单位)。如果没有读取数据,那将等待5秒钟然后返回。但是,如果它正在进行或阅读我认为它也可能会返回,所以要小心。我从来没有对串行API做任何事情,所以我不确定那里是否有这样的设置。

答案 4 :(得分:2)

这是一个双线程解决方案。

实施例

Thread tParent = new Thread(new ThreadStart(() =>
{
    Thread t = new Thread(AsyncMethod);
    t.Start();
    Thread.Sleep(5000);
    if (t.IsAlive) t.Abort();
}));

记住:

使用这样的方法是一种不好的做法。建议不要调用Thread.Abort()。请改用Thread Synchronization使用WaitHandles。例如,AutoResetEvent

答案 5 :(得分:1)

我想你需要一个观察者线程。同时启动另一个线程并将串行端口线程作为该线程的参数传递。以五秒钟的睡眠启动观察者,并检查线程的状态。

现在关于终止线程,请参阅alex的答案,它恰到好处!