Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果未返回,则在间隔后终止线程_C#_.net_Multithreading_Intervals_Terminate - Fatal编程技术网

C# 如果未返回,则在间隔后终止线程

C# 如果未返回,则在间隔后终止线程,c#,.net,multithreading,intervals,terminate,C#,.net,Multithreading,Intervals,Terminate,我有一个线程可以从网络或串行端口获取一些数据。如果在5秒内没有收到数据,线程必须终止(或返回false) 换句话说,如果运行线程的时间超过5秒,它必须停止 我是用C#编写的,但是任何.NET语言都可以。如果您使用托管代码来阻止线程,可以使用thread.Abort来中止执行。如果您使用的是第三方代码或COM互操作,则无法终止线程执行。唯一的方法是将线程.isBackroundThread设置为true,然后终止进程…我想您需要一个观察线程。同时启动另一个线程,并将串行端口线程作为该线程的参数传递

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

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


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

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

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


现在,关于终止线程,请参见alex的回答,它刚刚好

任何一种机制都应允许您指定读取超时。例如,在执行读取之前,可以设置为5000。您应该能够对串行端口执行类似的操作

已超时的读取将从
Stream.read()
返回0——这是如何判断是否实际发生超时的方法


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

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

有两种方法:

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


建议:我会坚持第一种解决方案,因为它会带来更干净、可维护的设计。但是,在某些情况下,可能需要提供“硬”中止此类工作线程的方法。

这是一种双线程解决方案

例子: 记得:
使用这样的方法是不好的做法。调用
Thread.Abort()
不是推荐的方法。使用
线程同步
改为使用
WaitHandles
。例如,<代码> AutoReTebug事件/代码> .< /P>我使用的是原生C++ +DLL和DLICONTIONTION.<代码>线程.BABUTE()/<代码>被禁止.NET 2,并且使用它被认为是不好的实践。我知道,并且我知道它可能引起的所有问题,我说“如果您使用托管代码”,则导致终止一段时间(…){}。使用
线程进行循环。中止
完全可以。没有关键部分……正如我在其他回答中提到的,
Thread.Abort()
已被弃用,它甚至不会中止在非托管代码中阻塞的线程。@cdhowie工作线程不必在单个非托管API调用中无限期阻塞。它可能正在对接收到的数据执行更复杂的处理,因此在某些情况下,“Thread.Abort()”可能是有效的解决方案。但是,一般来说,你是正确的。但是,<代码>流产()/<代码>使进程处于不确定的状态,因为线程可能已经在关键部分的中间中止。这就是为什么不应该使用它。请检查一下这是否正确?[code]ThreadPool.QueueUserWorkItem((obj=>{Thread workerThread=new Thread(o=>{for(inti=0;i<10000000;i++){});workerThread.Start();if(!workerThread.Join(new TimeSpan(0,0,5))){workerThread.Abort();MessageBox.Show(“Aborted”);}});[/code]@Mahdi示例似乎是正确的。但请注意,空的“for”将执行得非常快,您不会看到“Aborted”消息。最好使用
Thread.Sleep(…)
来模拟工作负载并使用算法。另外,我不太了解线程池和独立线程的组合。然而,正确的设计取决于您的最终目标。您正在抛出
不推荐的
,但MSDN库文章(2.0和4.0)对此完全沉默。当然没有[过时]。你真的应该把你的陈述的来源记录下来。@Hans:社区或多或少都不赞成这种说法。在推理方面做得很好。
Abort()
可以做的最糟糕的事情之一是导致线程无法正确释放获取的锁。哦,他们试图向他们发送一封有关此问题的电子邮件,但他们从未响应。我出于怨恨改变了一个结构。更好的答案是
Thread tParent = new Thread(new ThreadStart(() =>
{
    Thread t = new Thread(AsyncMethod);
    t.Start();
    Thread.Sleep(5000);
    if (t.IsAlive) t.Abort();
}));