Many systems are turning to message brokers to provide the architecture for service oriented architecture - often allowing for cross-platform mixed environment computing. This provides new considerations in that the response time from the broker is variable. If a broker is over-loaded, it will be slow - but in most cases, remote services are executed in environments with more resources than local clients.
In order to create a client library, which abstracts out the message broker service, System.Threading.Tasks can be used. With this design pattern, the client begins listening for the broker's response before the request to the broker is even written. This accounts for the case in which the broker responds quicker than the client can start listening - and also accounts for long-wait-time responses from the broker.
For the following code, assume ListenForBroadcast() returns some concrete type of IReturnedValue, and RequestBroadcastService() returns void.
// using System.Threading.Tasks;
IReturnedValue ret = null;
var readTask = new Task(
() => {
// Listen for the response
ret = (IReturnedValue)ListenForBroadcast();
});
var writeTask = new Task(
() => {
// Make the request
RequestBroadcastService();
});
// Start reading before the request is written
readTask.Start();
writeTask.Start();
// wait for tasks
Task.WaitAll(readTask, writeTask);
return ret;
The key to returning a value, while allowing for tasks to execute silmotaneously in the background is the use of Task.WaitAll() within the same scope as the earlier-defined return variable. If the read task fails - or times out, the result will be null. Try-catch blocks may be used - but it is encouraged to do this within the ListenForBroadcast() or RequestBroadcastService() methods.