我有一个线程从网络或串行端口获取一些数据。如果 5 秒内没有收到数据,线程必须终止(或返回 false)。
换句话说,如果线程运行时间超过 5 秒,它必须停止。
我用 C# 编写,但任何 .NET 语言都可以。
我有一个线程从网络或串行端口获取一些数据。如果 5 秒内没有收到数据,线程必须终止(或返回 false)。
换句话说,如果线程运行时间超过 5 秒,它必须停止。
我用 C# 编写,但任何 .NET 语言都可以。
有两种方法:
从网络或串口读取数据的线程可以测量从它开始时经过的时间,并等待数据不超过剩余时间。网络通信 API 通常提供指定操作超时的方法。因此,通过做简单的DateTime
算术,您可以在工作线程中封装超时管理。
使用另一个线程(或者如果可行的话在主线程中执行)等待工作线程在一定的时间限制内完成,如果没有,则中止它。像这样:
// start the worker thread
...
// give it no more than 5 seconds to execute
if (!workerThread.Join(new TimeSpan(0, 0, 5)))
{
workerThread.Abort();
}
建议:我会坚持第一个解决方案,因为它会带来更清洁和可维护的设计。但是,在某些情况下,可能有必要为此类工作线程的“硬”中止提供方法。
任何一种机制都应该允许您在读取时指定超时。例如,您可以NetworkStream.ReadTimeout
在执行读取之前设置为 5000。您应该能够为串行端口做类似的事情。
已超时的读取将返回 0 Stream.Read()
- 这是您可以判断是否实际发生超时的方法。
请注意,Thread.Abort()
对于可能导致的一些严重问题,从 .NET 2.0 开始不推荐使用 using。理论上你可以使用Thread.Interrupt()
,但是当线程在非托管代码(包括 I/O)中被阻塞时,这不会做任何事情。使用读取超时是解决此问题的正确方法。
如果您使用托管代码来阻塞线程,您可以使用它Thread.Abort
来中止执行。如果您使用的是第 3 方代码或 COM 互操作,则无法终止线程执行。唯一的方法是将设置Thread.isBackroundThread
为true,然后终止进程......
您提到您正在从“网络”阅读。如果您NetworkStream
用于阅读,则可以指定ReadTimeout
5000 (以毫秒为单位)。如果没有读取数据,它将等待 5 秒然后返回。但是,如果它正在处理或阅读中,我认为它也可能会返回,所以要小心。我从来没有对串行 API 做过任何事情,所以我不确定那里是否有这样的设置。
这是一个双线程解决方案。
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
using WaitHandles
。例如,AutoResetEvent
。
我想你需要一个观察者线程。同时启动另一个线程,并将串口线程作为该线程的参数传递。以五秒钟的睡眠启动观察者并检查线程的状态。
现在至于终止线程,请参阅alex的答案,它刚刚好!