中止正在等待 Read() 语句的线程(C# 套接字编程)
Posted
技术标签:
【中文标题】中止正在等待 Read() 语句的线程(C# 套接字编程)【英文标题】:Aborting a thread, which is waiting on Read() statement (C# Socket Programming) 【发布时间】:2020-01-25 21:06:43 【问题描述】:我有一个用于 TCP-IP 客户端的 WinForms 应用程序。一旦客户端连接到本地主机服务器,我就会启动一个线程t1
,它进入一个无限循环以继续接收来自服务器的消息。
当服务器不发送任何消息时,线程无限等待语句m_DeviceServerStream.Read(instream, 0, buffersize);
,如下面的代码所示。
Thread t1;
TcpClient m_DeviceClientSocket = new TcpClient();
NetworkStream m_DeviceServerStream = default(NetworkStream);
public void StartClient()
m_DeviceClientSocket.Connect(m_DeviceURL, m_DevicePort);
m_DeviceServerStream = m_DeviceClientSocket.GetStream();
t1 = = new Thread(KeepReceiveingMessages);
t1.Start();
public void StopClient() //On Stop Button-click
t1.Abort();
public void KeepReceiveingMessages()
while(true)
_dataServiceConnected.Waitone()
try
var buffersize = m_DeviceClientSocket.ReceiveBufferSize;
byte[] instream = new byte[buffersize];
m_DeviceServerStream.Read(instream, 0, buffersize) //THREAD T1 KEEP WAITING HERE TILL A MESSAGE IS RECEIVED FROM THE SERVER
catch(Exception e)
_dataServiceConnected.Reset(); //do not try to eneter again till we have a working connection
问题:如果我想关闭客户端应用程序,我想优雅地完成线程。但我发现即使我调用t1.Abort()
,线程t1
也会继续运行(如Visual Studio Thread-Debug 窗口中所示)。 Aborting a thread is not a good practice,那我应该如何结束线程呢?
【问题讨论】:
关闭流。异步版本见***.com/a/12893018/11683。 @GSerg:我关闭了流并调用了t1.Join(1000);
,但线程仍在运行。
我只是在查看另一个帖子的类似代码。我发现以下内容: if(ns.DataAvailable) ns.Read(new byte[100], 0, 100);见***.com/questions/1993635/…
@skm 当您关闭流时,Read
调用会返回。因为您有一个无限循环,所以再次调用它,这会引发异常,因为流已关闭。如果您没有观察到该异常,则意味着这不是您正在运行的实际代码。
@GSerg:我确实有捕获块,一旦我关闭流,线程就会进入捕获块。但是,我仍然无法中止线程(可能是因为我有一个Waitone() statement at the beginning of the while loop
)。我已经在帖子中更新了我的代码。
【参考方案1】:
您应该使用WaitOne(Int32) 来等待超时。如果 WaitOne(int32) 返回 false,则表示超时已过期且未发出事件信号。然后,您可以检查是否需要优雅地退出线程。
private bool volatile shouldCancel; //Dirty, but will work on Intel hardware :-)
public void KeepReceiveingMessages()
while(true)
bool signaled = _dataServiceConnected.Waitone(100);
if (!signaled && shouldCancel) return;
try
var buffersize = m_DeviceClientSocket.ReceiveBufferSize;
byte[] instream = new byte[buffersize];
m_DeviceServerStream.Read(instream, 0, buffersize) //THREAD T1 KEEP WAITING HERE TILL A MESSAGE IS RECEIVED FROM THE SERVER
catch(Exception e)
_dataServiceConnected.Reset(); //do not try to eneter again till we have a working connection
【讨论】:
以上是关于中止正在等待 Read() 语句的线程(C# 套接字编程)的主要内容,如果未能解决你的问题,请参考以下文章
C#错误之 System.Threading.ThreadAbortException:正在中止线程