2

Webからデータを読み取る関数(以下のコードを参照)があります。この関数の問題は、高速で戻る場合もあれば、無期限に待機する場合もあることです。スレッドは、一定期間待ってから戻るのに役立つと聞きました。

スレッドを「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

このコードを実行しているスレッドに(まともな)2番目のスレッドを中断させることはできません。代わりに読み取りタイムアウトを使用してください。

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

にReadTimeoutを設定しSslStreamて、への呼び出しがRead指定された時間が経過するとタイムアウトになるようにすることができます。

于 2012-07-05T17:33:23.103 に答える
1

メインスレッドをブロックしたくない場合は、非同期パターンを使用します。

何を達成しようとしているのかを正確に知らなくても、UI /メインスレッドをブロックせずに、応答にかなり時間がかかる可能性のあるSSLストリームからデータを読み取りたいようです。

BeginReadを使用する代わりに、非同期で読み取りを行うことを検討できます。

このアプローチを使用して、Readがデータを読み取り、指定されたバッファーに配置するたびに呼び出されるコールバックメソッドを定義します。

スリープするだけで(を使用するか、 ReadTimeoutをにThread.Sleep設定するかどうかに関係なく)、このコードが実行されているスレッドがブロックされます。SslStream

于 2012-07-05T17:34:24.710 に答える
0

応答を待つ独自のスレッドにReadMessageを配置して、非同期になるように設計します。答えが提供されたら、出力を処理するためにメインコードに戻るイベントを作成します。

于 2012-07-05T17:34:00.353 に答える