我有一个功能(请参阅下面的代码),它从网络上读取一些数据。这个函数的问题在于它有时会快速返回,但是另一次它将无限期地等待。我听说线程帮助我等待一段时间并返回。
请告诉我如何使线程等待'x'秒并在没有记录活动的情况下返回。我的函数也返回一个字符串作为结果,是否可以在使用线程时捕获该值?
private string ReadMessage(SslStream sslStream)
{
// Read the message sent by the server.
// The end of the message is signaled using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
try
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.ASCII.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF.
}
catch (Exception ex)
{
throw;
}
return messageData.ToString();
}
对于安德烈·卡利尔的评论:
我需要读取/写入SSL服务器的某些值。对于每个写操作,服务器都会发送一些响应,ReadMessage负责读取传入的消息。我发现了ReadMessage的情况(sslStream.Read(buffer,0,buffer.Length);)永远等待。为了解决这个问题,我考虑了可以等待'x'秒并在此之后返回的线程。以下代码演示了ReadMEssage的工作原理
byte[] messsage = Encoding.UTF8.GetBytes(inputmsg);
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
outputmsg = ReadMessage(sslStream);
// Console.WriteLine("Server says: {0}", serverMessage);
// Close the client connection.
client.Close();
答案 0 :(得分:3)
你不能(理智地)让第二个线程中断你执行此代码的线程。改为使用read timeout:
private string ReadMessage(SslStream sslStream)
{
// set a timeout here or when creating the stream
sslStream.ReadTimeout = 20*1000;
// …
try
{
bytes = sslStream.Read(…);
}
catch (IOException)
{
// a timeout occurred, handle it
}
}
顺便说一句,以下结构毫无意义:
try
{
// some code
}
catch (Exception ex) {
throw;
}
如果你正在做的只是重新抛出,你根本不需要try..catch
块。
答案 1 :(得分:2)
您可以在SslStream
上设置ReadTimeout,以便在指定的时间后对Read
的调用会超时。
答案 2 :(得分:1)
如果您不想阻止主线程,请使用异步模式。
在不确切知道您要实现的目标的情况下,听起来您想要从SSL流中读取可能需要很长时间才能响应的数据,而不会阻止您的UI /主线程。
您可以考虑使用BeginRead
异步进行读取使用该方法,您可以定义每次Read读取数据并将其放入指定缓冲区时调用的回调方法。
只是睡觉(无论是使用Thread.Sleep
还是在SslStream
上设置ReadTimeout)都会阻止此代码运行的线程。
答案 3 :(得分:0)
通过将ReadMessage放在自己的线程中等待答案,将其设计为异步。提供答案后,创建一个返回主代码的事件来处理其输出。