接口和异步方法

时间:2012-11-26 21:34:18

标签: c# interface async-await

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:58)

async不是签名的一部分,因此您实际上不需要关心实现接口的方法是否为async,您只需要关注属性的类型,返回类型,方法的名称和可访问性。

真正的区别在于,您的async方法需要返回TaskTask<T>,而非异步方法最有可能是直接返回void或某种类型T

如果您希望“面向未来”您的应用程序的一个选项是确保所有接口都返回TaskTask<T>,并且对于您的EF4 / EF5实现,您将结果打包完成任务即使它们是同步执行的。

在.NET 4.5中添加了

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}}结果。