I understand we should generally avoid async over sync and vice versa. Here are two posts by Stephen Toub which explain this nicely:
- Should I expose asynchronous wrappers for synchronous methods?
- Should I expose synchronous wrappers for asynchronous methods?
We use WCF to communicate across tiers and have a shared contract used both by the service and client. The client uses ChannelFactory<TContract>
to create the proxy and channel. One big benefit of this is that we don't have to manually update our [many] service references and we get automatic compile-time checking on both sides if the interface changed. However, it also means we can't keep the server-side interface synchronous (not returning a Task<Result>
) and also have the client proxy be asynchronous (return Task<Result>
due to the network hop).
So my question is, is there any real harm/downside to have the contract return type Task<Result>
and on the server-side just do a return Task.FromResult(SyncCode());
? We're effectively doing async over sync on the server side to enable async on the client side, but the network is technically already async anyway. Task.FromResult()
shouldn't create any additional threads or introduce any significant overhead. Does this seem like a reasonable exception to the rule?
In other words, I may have an implementation similar to the following:
public PersonResult GetPerson(int id)
{
return SyncCode();
}
public Task<PersonResult> GetPersonAsync(int id)
{
return Task.FromResult(GetPerson(id));
}