2

我有一个从网上读取一些数据的函数(请参见下面的代码)。这个函数的问题是有时它会很快返回,但有时它会无限期地等待。我听说线​​程可以帮助我等待一段确定的时间并返回。

你能告诉我如何让一个线程等待'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

4 回答 4

3

您不能(理智地)让第二个线程中断您正在执行此代码的线程。改为使用读取超时

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块。

于 2012-07-05T17:35:15.040 回答
2

您可以在 上设置ReadTimeoutSslStream以便调用Read将在指定的时间后超时。

于 2012-07-05T17:33:23.103 回答
1

如果您不想阻塞主线程,请使用异步模式

在不确切知道您要实现的目标的情况下,听起来您想从可能需要很长时间才能响应的 SSL 流中读取数据,而不会阻塞您的 UI/主线程。

您可以考虑使用BeginRead异步读取

使用这种方法,您定义了一个回调方法,每次 Read 读取数据并将其放入指定的缓冲区时都会调用该方法。

只是睡觉(无论是使用还是通过在 上Thread.Sleep设置ReadTimeoutSslStream)都会阻塞运行此代码的线程。

于 2012-07-05T17:34:24.710 回答
0

通过将 ReadMessage 放在自己的线程中等待答案,将其设计为异步的。提供答案后,创建一个事件返回到主代码以处理其输出。

于 2012-07-05T17:34:00.353 回答