接口和asynchronous方法
我有一个应用程序。 此应用程序使用一个接口来访问数据库。 这个接口可以由许多类来实现。 例如,一个使用EF 4.4,但其他类可以使用更有效的EF5。 在将来也许我会使用EF6,因为它使用asynchronous方法。 在这个例子中,所有的方法都使用EF,但也可以使用其他方法。
应用程序编码一次,使用接口,并根据configuration文件,使用一个实现或其他,所以我只需要修改代码在一个地方,构造函数,在类的实例化中添加新的选项分配给接口。
目前所有类的方法都不是async
,但是将来如果我使用EF6,我想使用asynchronous方法,所以我不知道是否有可能使用EF6的类并实现了接口可以使用async
方法。
对于EF6的asynchronous方法,我会使用async / awiat模式,所以在我的类的方法中,我需要使用async属性。 当我调用EF6的asynchronous方法时,这让我使用await
关键字。
但是这个类可以实现第一次使用同步方法的接口吗?
有没有办法在主应用程序中使用许多实现而不需要修改代码? 一些实现将使用asynchronous方法,而其他实现将是同步的。
async
不是签名的一部分,所以你实际上不需要关心实现接口的方法是否是async
,你只需要关心属性的types,返回types,方法的名称和可访问性。
真正的区别在于你的async
方法需要返回一个Task
或一个Task<T>
,而非asynchronous方法很可能是直接返回void
或者某个typesT
如果你想“未来certificate”你的应用程序的一个select是确保所有的接口返回Task
或Task<T>
和你的EF4 / EF5实现你把结果包装在一个完成的任务,即使他们同步执行。
Task.FromResult
是在.NET 4.5中添加的,但是如果你没有它,你可以很容易的编写自己的代码:
public static Task<T> FromResult<T>(T result) { var tcs = new TaskCompletionSource<T>(); tcs.SetResult(result); return tcs.Task; }
您也可以编写一个CompletedTask
方法, CompletedTask
方法简单地返回已经完成的任务:(由于效率的原因,它caching了一个任务。)
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; }
这两个方法将简化所有方法返回某种types的Task
,尽pipe这样做会使您的代码变得更加混乱,直到您能够使用C#5.0来await
结果。