C# 接口和异步方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13573516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Interfaces and async methods
提问by álvaro García
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 that is more efficient. In the future perhaps I will use EF6 because it uses async methods. In this example all the methods use EF, but perhaps other options can be use other ways.
我有一个应用程序。这个应用程序使用一个接口来访问数据库。这个接口可以由许多类来实现。例如,一个使用 EF 4.4,但其他类可以使用效率更高的 EF5。将来我可能会使用 EF6,因为它使用异步方法。在此示例中,所有方法都使用 EF,但也许其他选项可以使用其他方式。
The application is coded once, using the interface, and according to the config file, use one implementation or the other, so I only need to modify the code in one place, the constructor, to add the new option in the instantiation of the class that is assigned to the interface.
应用程序编码一次,使用接口,并根据配置文件,使用一个实现或另一个,所以我只需要修改一个地方的代码,构造函数,在类的实例化中添加新选项即分配给接口。
At the moment all the methods of the classes are not async, but in the future if I use EF6 I would like to use the async methods, so I don't know if it is possible that the class that use EF6 and implements the interface can use the asyncmethods.
目前类的所有方法都不是async,但是以后如果我用EF6我想用异步方法,所以我不知道使用EF6并实现接口的类是否可以使用async方法。
For the async methods of EF6, I would use the async/awiat pattern, so in the method of my class I need to use the async attribute. This lets me use the awaitkeyword when I call to the async method of EF6.
对于 EF6 的异步方法,我将使用 async/awiat 模式,因此在我的类的方法中,我需要使用 async 属性。这让我可以在await调用 EF6 的异步方法时使用关键字。
But this class can implement the interface that in a first time is for synchronous methods?
但是这个类可以实现第一次用于同步方法的接口吗?
Is there some way that in the main application I can use many implementations without the need to modify the code? Some implementations will use async methods while others will be synchronous.
有什么方法可以在主应用程序中使用许多实现而无需修改代码?一些实现将使用异步方法,而其他实现将是同步的。
采纳答案by Servy
asyncisn't a part of the signature, so you don't actually need to be concerned with whether the method implementing the interface is asyncor not, you only need to be concerned with the types of the properties, the return type, the name of the method, and the accessibility.
async不是签名的一部分,所以你实际上不需要关心实现接口的方法是否async存在,你只需要关心属性的类型,返回类型,名称方法和可访问性。
The realdifference is that your asyncmethods will need to return a Taskor a Task<T>, whereas the non-async methods are most likely currently returning voidor some type, Tdirectly.
在真正的区别是,你的async方法就需要返回一个Task或一个Task<T>,而非异步方法最有可能返回当前void或某些类型的,T直接。
If you want to "future proof" your application one option is to ensure that all of your interfaces return Taskor Task<T>and that for your EF4/EF5 implementations you wrap your results in a completed task even though they're executed synchronously.
如果您想要“面向未来”您的应用程序,一个选择是确保您的所有接口都返回,Task或者Task<T>对于您的 EF4/EF5 实现,您将结果包装在一个已完成的任务中,即使它们是同步执行的。
Task.FromResultwas added in .NET 4.5, but if you don't have it you can write your own easily enough:
Task.FromResult已在 .NET 4.5 中添加,但如果您没有它,您可以轻松编写自己的:
public static Task<T> FromResult<T>(T result)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(result);
return tcs.Task;
}
You can also write a CompletedTaskmethod that simply returns a task that has already completed: (It caches a single task for efficiency reasons.)
您还可以编写一个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;
}
Those two methods will simplify the process of having all of your methods returning some type of Task, although doing this will make your code a bit messier until you're able to use C# 5.0 to be able to awaitthe result.
这两种方法将简化其所有的方法返回某种类型的过程中Task,虽然做这会让你的代码有点混乱,直到你能够使用C#5.0才能够await结果。

