我有一个申请。此应用程序使用接口访问数据库。该接口可以由许多类实现。例如,一个使用EF 4.4,但其他类可以使用效率更高的EF5。在将来,我可能会使用EF6,因为它使用异步方法。在此示例中,所有方法都使用EF,但也许其他选项可以使用其他方式。
应用程序编码一次,使用接口,并根据配置文件,使用一个实现或另一个,所以我只需要在一个地方修改代码,构造函数,在实例化中添加新选项分配给接口的类。
目前所有类的方法都不是async
,但将来如果我使用EF6我想使用异步方法,所以我不知道是否有可能是类使用EF6并实现接口可以使用async
方法。
对于EF6的异步方法,我会使用async / awiat模式,所以在我的类的方法中我需要使用async属性。这使我在调用EF6的异步方法时可以使用await
关键字。
但是这个类可以实现第一次用于同步方法的接口吗?
有没有办法在主应用程序中我可以使用许多实现而无需修改代码?一些实现将使用异步方法,而其他实现将是同步的。
答案 0 :(得分:58)
async
不是签名的一部分,因此您实际上不需要关心实现接口的方法是否为async
,您只需要关注属性的类型,返回类型,方法的名称和可访问性。
真正的区别在于,您的async
方法需要返回Task
或Task<T>
,而非异步方法最有可能是直接返回void
或某种类型T
。
如果您希望“面向未来”您的应用程序的一个选项是确保所有接口都返回Task
或Task<T>
,并且对于您的EF4 / EF5实现,您将结果打包完成任务即使它们是同步执行的。
Task.FromResult
,但是如果你没有它,你可以轻松编写自己的:
public static Task<T> FromResult<T>(T result)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(result);
return tcs.Task;
}
您还可以编写一个CompletedTask
方法,该方法只返回已完成的任务:(出于效率原因,它会缓存单个任务。)
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;
}
这两个方法将简化让所有方法返回某种类型的Task
的过程,尽管这样做会使你的代码变得有点麻烦,直到你能够使用C#5.0才能{ {1}}结果。