There are many questions asking if mixing asynchronous and synchronizing code should be done.
Most answers say that it is a bad idea to expose sync wrappers for asynchronous methods and to expose asynchronous wrappers for synchronization methods.
However, none of the answers relate to a specific scenario in which you should mix asynchronous and synchronizing code, and how to avoid common errors that arise because of this.
See the following example:
class Program { static void Main(string[] args) { IContract signatory = new SyncSignatory(); signatory.FullfillContractAsync().Wait(); signatory = new AsyncSignatory(); signatory.FullfillContractAsync().Wait(); } }
using System.Threading.Tasks; interface IContract { Task FullfillContractAsync(); }
using System.Threading.Tasks; class AsyncSignatory : IContract { public async Task FullfillContractAsync() { await Task.Delay(5000); } }
using System.Threading; using System.Threading.Tasks; class SyncSignatory : IContract { public Task FullfillContractAsync() { Thread.Sleep(5000); return Task.FromResult<object>(null); } }
Or:
using System.Threading; using System.Threading.Tasks; class SyncSignatory : IContract { public Task FullfillContractAsync() { return Task.Run(() => Thread.Sleep(5000)); } }
In this example, SyncSignatory and AsyncSignatory are two interchangeable classes because they perform similar functions, but they perform these functions in different ways - synchronously and asynchronously.
How do you mix contract synchronization and asynchronous code while avoiding common error scenarios?
What about a user who expects syncSig to start async, but instead performs synchronization?
What about a user who could optimize syncSig by running async, but not longer, because he assumes he is already running async?
c # asynchronous interface
Francisco Aguilera Dec 30 '16 at 18:37 2016-12-30 18:37
source share