I have to write some middle-ware code that requires me to return a Task object. My middle-ware code also uses a framework that asynchronously sends data to a connected client, returning a Task.
Pretty straight forward so far.
However my use case is that I have many connected clients. So my question is basically, what is the most sensible way to call each client's async Send
method, and more importantly, what is the Task
I should be returning. I'm using c# 5.
class Client // some framework
{
public Task Send(Object message)
{
// does its thing somehow, returns a Task
}
}
interface Handler<TMessage> // some framework
{
Task Handle(TMessage msg);
}
class Middleware : Handler<Object> // my middleware implementation code
{
List<Client> clients;
public Task Handle(Object msg)
{
//i do some stuff here before calling each client's Send method
return Task.Run(() => clients.ForEach(client => client.Send(msg))); <-- my current solution
}
}
So in short, I receive a message (the handler), I perform some custom logic (filtering clients etc) and then call each clients async Send
method. Depending on the nature of the custom logic which will vary from case to case, I may want to wrap that code inside the Task
also. Any advice on this would also be greatly appreciated.
My confusion is, should I be returning the outer Task
that I've created as is? Or is there some other preferred way of executing each async method that I'm not aware of.
EDIT:
The Send
method is asynchronous even though it's not named SendAsync
. Keep in mind it is a framework call, so I can't rename it to SendAsync as suggested. However, rest assured that it is an asynchronous call under the covers, and returns a Task
.
Given the truly asynchronous nature of the call, is my usage of:
return Task.Run(() => clients.ForEach(client => client.Send(msg)));
going to cause any issues, given I don't want to wait for each client's asynchronous Send() method to run to completion?
To clarify: by 'cause any issues', I mean is there any cause for concern in simply executing the above? Deadlocks, Exceptions that go unobserved etc..? I ask because I know there are a lot of subtleties in asynchronous programming that aren't always obvious, that someone with a better understanding than me might be able to point out as a possible issue, or perhaps know of a better way to achieve what I'm aiming for...