接口和异步方法

Álv*_*cía 49 c# interface async-await

我有一个申请.此应用程序使用接口访问数据库.该接口可以由许多类实现.例如,一个使用EF 4.4,但其他类可以使用效率更高的EF5.在将来,我可能会使用EF6,因为它使用异步方法.在此示例中,所有方法都使用EF,但也许其他方法可以使用其他方法.

应用程序编码一次,使用接口,并根据配置文件,使用一个实现或另一个,所以我只需要在一个地方修改代码,构造函数,在类的实例化中添加新选项分配给接口的.

目前所有类的方法都没有async,但是将来如果我使用EF6我想使用异步方法,所以我不知道使用EF6并实现接口的类是否可能使用async方法.

对于EF6的异步方法,我会使用async/awiat模式,所以在我的类的方法中我需要使用async属性.这让我await在调用EF6的异步方法时使用关键字.

但是这个类可以实现第一次用于同步方法的接口吗?

有没有办法在主应用程序中我可以使用许多实现而无需修改代码?一些实现将使用异步方法,而其他实现将是同步的.

Ser*_*rvy 59

async不是签名的一部分,所以你实际上并不需要关心实现接口的方法是否合适async,你只需要关注属性的类型,返回类型,名称方法和可访问性.

真正的区别是,你的async方法就需要返回一个Task或一个Task<T>,而非异步方法最有可能返回当前void或某些类型的,T直接.

如果您希望"将来证明"您的应用程序,一个选项是确保您的所有接口都返回,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;
}
Run Code Online (Sandbox Code Playgroud)

您还可以编写一个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;
}
Run Code Online (Sandbox Code Playgroud)

这两种方法将简化使所有方法返回某种类型的过程Task,尽管这样做会使您的代码变得更加混乱,直到您能够使用C#5.0才能获得await结果.

  • 在这种情况下(您的操作自然是异步的),您可以使所有方法返回`Task`或并行创建同步和异步方法. (6认同)