我在C#中使用一个线程,我希望它在40秒后停止。 事实上,我开始它,它运行40秒然后它停止了。 是否可以使用超时或计时器?
答案 0 :(得分:2)
有两种方法:
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 :(得分:1)
当计时器到期时,当然可以踢一个计时器然后杀死一个线程,但是不要自己这样做,你可能更好地使用像Richter Power Threading library这样的实用程序来允许你设置超时关于异步任务。
你打算如何阻止你的线程?中止线程不是一个好主意(如果这是你打算做的) - 例如有关详情,请参阅aborting timer threads。使用类似Power Threading库的东西可以让你更优雅地超时一个线程,如果你自己选择自己做,你需要考虑如何优雅地结束一个线程。
答案 2 :(得分:1)
根据阻塞操作的级别,及时性的容差(即它必须停止的接近40秒)以及线程必须如何优雅地退出,有几种选择。
合作,内部
如果线程不需要外部控制或信号,并且阻塞操作通常是短暂的(当然短于40秒),它可以使用Stopwatch来测量经过的时间,然后优雅地退出。或者,您可以使用DateTime
标记开始时间,然后通过从DateTime.Now
中减去该值来定期检查。
合作,外部
这是在确定它之后的另一个线程是第二个退出的时候,向另一个线程发送信号。这意味着另一个线程必须通过实际检查条件来配合,这意味着任何阻塞操作(如I / O)都不能长时间阻塞,因此可以检查。以下是一些选择:
s
,并将s.Token
作为状态数据传递给线程 T2 。 T2会定期检查s.Token.
IsCancellationRequested
。<强>非合作强>
当 T2 无法检查某些条件(即无法合作)时,这是一个可能的选择,因为它执行了一些无法控制的长阻塞操作,例如调用第三个-party API,不提供异步或可取消选项。在这种情况下, T1 可以通过执行Thread.Join(
超时 )
,然后通话,优雅地尝试停止 T2 到Thread.Abort()
注意:最后要避免使用,并且已在框架中弃用。
最后,
如果您在 T2 中调用Thread.Sleep
,则可以将以下两种技术中的一项与上述技术结合使用:
Thread.Interrupt
,可能是在检查 T2 的ThreadState为ThreadState.WaitSleepJoin
之后。 Thread.Sleep
实现“旋转睡眠”。这基本上就像一个普通的睡眠,但你睡眠时间较短 N 次,并返回一个布尔值,表明较小的睡眠是否被中断(当然它必须捕获这个异常)。然后在为true时退出(例如,而不是Thread.Sleep(10000)
,您执行SpinSleep(20, 50)
。答案 3 :(得分:0)
你可以通过在40秒超时的线程上使用Join来实现这样的目的。在此之后,您可以尝试关闭线程(您必须自己提供此方法)或使用Abort - 但不建议这样做。