2

私は何度もこの問題に出くわし、ほとんどはハックで解決しましたが、それを行う「適切な」方法を見たいと思っています。

私は、エンドポイントが「クエリ」を要求し、それに対して「応答」を受け取るという方法で、RPC に非常に似た通信プロトコルを作成しています。

ここで... クエリを送信し、その質問に対する応答を待って返す SendCommand という関数を実装したいと思います。

だから私は次のようなことができます

int outside_temp = SendCommand(What is the temperature outside).ToInt();

これに関する問題は、メッセージが非同期で送受信され、新しいメッセージが到着したこと、およびそれが何であったかをイベントによって通知されることです。上記のクエリへの応答が到着するまでスレッドをブロックし、そのデータ コンテンツを抽出して、呼び出し元に返す必要があります。

私の問題は、スレッドをブロックすることです。スレッドをブロックすることは問題ではありません。これはマルチスレッド アプリについて話しているため、UI がフリーズすることはありませんが、問題は、これを実現する正しい方法は何ですか?

SendCommand関数内でセマフォを初期化し、それを待って、メッセージ受信イベントハンドラーでセマフォを解放するという行に沿って何かを考えています(正しいメッセージであることを確認した後)?

よろしく、 axos88

4

2 に答える 2

5

あなたの質問は、現在のスレッドをブロックして答えを待つことについてですか? ManualResetEvent を使用して、呼び出し元とコールバックを同期します。

コールバック メソッドを受け入れるオブジェクトの Send メソッドを介して rpc 呼び出しを送信できると仮定すると、次のSendCommandようにメソッドをコーディングできます。

int SendCommand(int param)
{
    ManualResetEvent mre = new ManualResetEvent(false);

    // this is the result which will be set in the callback
    int result = 0;

    // Send an async command with some data and specify a callback method
    rpc.SendAsync(data, (returnData) =>
                       {
                           // extract / process your return value and 
                           // assign it to an outer scope variable
                           result = returnData.IntValue;
                           // signal the blocked thread to continue
                           mre.Set();
                       });

    // wait for the callback
    mre.WaitOne();
    return result;
}
于 2012-10-17T09:55:12.400 に答える
0

できることは、SendCommand(..)を呼び出す新しいスレッドをスピンし、SendCommandがシグナルを送信するまで、スレッドをスリープ状態で待つことです。

例えば:

volatile bool commandCompleted=false;
Thread sendCommandThread=new Thread(()=>{
   SendCommand(...,()=>{
 commandCompleted=true;
})

 while(!commandCompleted)
{

  Thread.Sleep(100);
}
});
于 2012-10-17T06:35:15.917 に答える