Reputation:
i have following scenario. I am running a tcp client where i get push notifications like heartbeats and other objects. I can also run commands against the server like GetWeather infos or something like that. Everytime i receive an object i raise an event which works pretty fine. But now i want to be able to request some data on the server and wait for it until the server responses the right object. During the request of an object other objects can also be send to me.
Here is some pseudocode:
Instead of:
TcpServer.ObjectReceived += ObjectReceivedMethod;
TcpServer.GetWeather();
public void ObjectReceived(object data)
{
}
I want:
var result = await TcpServer.GetWeather();
How can i transfer the Weather Info from ObjectReceived to the awaiting method?
KR Manuel
Upvotes: 1
Views: 473
Reputation: 457207
You want to use a TaskCompletionSource<T>
, something like this:
private Dictionary<Guid, TaskCompletionSource<WeatherResponse>> _weatherRequests;
public Task<WeatherResponse> GetWeatherAsync()
{
var messageId = Guid.NewGuid();
var tcs = new TaskCompletionSource<WeatherResponse>();
_weatherRequests.Add(messageId, tcs);
_server.SendWeatherRequest(messageId);
return tcs.Task;
}
public void ObjectReceived(object data)
{
...
if (data is ServerWeatherResponse)
{
var tcs = _weatherRequests[data.requestId];
_weatherRequests.Remove(data.requestId);
tcs.SetResult(new WeatherResponse(data));
}
}
This assumes that your server will associate requests with responses using a GUID id.
Upvotes: 3