简体   繁体   中英

C# blocking wait for response

I have stumbled upon this problem many times, mostly solved it with hacks, but would like to see a "proprer" way to do it.

I'm writing a communication protocol, very similar to RPC in a way that my endpoints ask "queries", to which they receive "replies".

Now... I would like to implement a function, called SendCommand, that would send out a query, and wait for the reply to that question, and return it.

So I could do something like

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

The problem with this is that the messages are send and received asynchronously, and I am notified by events that a new message has arrived, and what it was. I would need to block the thread until the reply to the mentioned query has arrived, extract its data content, and return it to the caller.

My problem is with blocking the thread. Blocking the thread is not a problem, we are talking about a multi-threaded app, so the UI would not freeze, etc., but the question is what is the correct way to achieve this?

I'm thinking something along the line of initializing a semaphore inside the SendCommand function, waiting for it, and release the semaphore in the message received event handler (after checking it was the correct message)?

Regards, axos88

So your question is about blocking the current thread and wait for the answer? I would use a ManualResetEvent to synchronise the caller and the callback.

Supposed you can send your rpc call via a Send method of an object which accepts a callback method, you can code your SendCommand method like this:

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;
}

What you could do is, spin a new thread that calls SendCommand(..) and just wait far the thread with sleeping until your SendCommand sends a signal.

For example:

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

 while(!commandCompleted)
{

  Thread.Sleep(100);
}
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM