有很多地方都处理了如何优雅终止C#线程。然而,它们依赖于循环或者if条件执行在一个循环内,这意味着当设置
以下是要处理的线程的循环:
stop
布尔标志后,线程会迅速退出。但是,如果我的线程并不是那样的呢? 在我的情况下,这是一个被设置为从服务器接收数据的线程,通常会在调用读取输入流中的数据时阻塞,但是没有提供数据,所以它会等待。以下是要处理的线程的循环:
while (true)
{
if (EndThread || Commands.EndRcvThread)
{
Console.WriteLine("Ending thread.");
return;
}
data = "";
received = new byte[4096];
int bytesRead = 0;
try
{
bytesRead = stream.Read(received, 0, 4096);
}
catch (Exception e)
{
Output.Message(ConsoleColor.DarkRed, "Could not get a response from the server.");
if (e.GetType() == Type.GetType("System.IO.IOException"))
{
Output.Message(ConsoleColor.DarkRed, "It is likely that the server has shut down.");
}
}
if (bytesRead == 0)
{
break;
}
int endIndex = received.Length - 1;
while (endIndex >= 0 && received[endIndex] == 0)
{
endIndex--;
}
byte[] finalMessage = new byte[endIndex + 1];
Array.Copy(received, 0, finalMessage, 0, endIndex + 1);
data = Encoding.ASCII.GetString(finalMessage);
try
{
ProcessMessage(data);
}
catch (Exception e)
{
Output.Message(ConsoleColor.DarkRed, "Could not process the server's response (" + data + "): " + e.Message);
}
}
代码块顶部的if
语句执行通常停止线程的优雅设置:检查标志,如果已设置则终止线程。然而,该线程通常会在几行后面找到等待,在stream.Read
处。
鉴于此,是否有任何方法可以优雅地终止此线程(即不使用Abort
),并清理其资源(有一个需要关闭的客户端)?
TcpClient
,你可以将其ReceiveTimeout
属性设置为任何你喜欢的值。可能甚至有一个构造函数可以让你在创建时设置它,尽管我不确定。 - Asad Saeeduddinstream.Read
中获取了完整的消息,但在单次读取期间可能只获取了 1/2 条消息。你真的应该在其中加入某种循环,检查'\0'
是否存在,如果消息没有空字符,则再次调用读取操作,然后将data
传递给ProcessMessage
。 - Scott Chamberlain