如何让线程等待特定秒

时间:2012-07-05 17:28:08

标签: c# multithreading

我有一个功能(请参阅下面的代码),它从网络上读取一些数据。这个函数的问题在于它有时会快速返回,但是另一次它将无限期地等待。我听说线​​程帮助我等待一段时间并返回。

请告诉我如何使线程等待'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();

4 个答案:

答案 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放在自己的线程中等待答案,将其设计为异步。提供答案后,创建一个返回主代码的事件来处理其输出。