Interfaces and Asynchronous Methods

I have an application. This application uses an interface to access the database. This interface can be implemented by many classes. For example, one uses EF 4.4, but other classes can use EF5, which is more efficient. In the future, perhaps I will use EF6 because it uses async methods. In this example, all methods use EF, but perhaps other parameters can be used in other ways.

The application is encoded once using the interface and in accordance with the configuration file uses one implementation or another, so I only need to change the code in one place, the constructor, to add a new parameter to the instance of the class assigned to the interface.

Currently all class methods are not async , but in the future, if I use EF6, I would like to use async methods, so I don’t know if it is possible that a class that uses EF6 and implements the interface can use async methods.

For EF6 asynchronous methods, I would use the async / awiat template, so in my class method I need to use the async attribute. This allows me to use the await keyword when I call the async method for EF6.

But can this class implement an interface that is designed for synchronous methods for the first time?

Is there a way that in the main application I can use many implementations without having to change the code? Some implementations will use asynchronous methods, while others will be synchronous.

+47
c # interface async-await
Nov 26 '12 at 21:34
source share
1 answer

async not part of the signature, so you really do not need to worry about whether the implementation method of the async interface is or not, you only need to consider the property types, return type, method name and availability.

The real difference is that your async methods will have to return Task or Task<T> , while non-asynchronous methods are most likely currently returning void or some type, T directly.

If you want the “future proof” of your application to be one of the options, make sure that all your interfaces return Task or Task<T> , and for your EF4 / EF5 implementations you complete the results in the completed task, even if they are executed synchronously.

Task.FromResult was added in .NET 4.5, but if you don't have one, you can write your own quite easily:

 public static Task<T> FromResult<T>(T result) { var tcs = new TaskCompletionSource<T>(); tcs.SetResult(result); return tcs.Task; } 

You can also write the CompletedTask method, which simply returns a task that has already been completed: (It caches one task for efficiency reasons.)

 private static Task _completedTask; public static Task CompletedTask() { return _completedTask ?? initCompletedTask(); } private static Task initCompletedTask() { var tcs = new TaskCompletionSource<object>(); tcs.SetResult(null); _completedTask = tcs.Task; return _completedTask; } 

These two methods will simplify the process when all your methods return some type of Task , although this will make your code a bit more messy until you can use C # 5.0 to be able to await result.

+54
Nov 26
source share



All Articles