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