如何在C#5.0中强制异步子覆盖

Lar*_*ann 46 c# abstract-class asynchronous async-await c#-5.0

我正在研究一个系统,其中多个客户端对象需要通过接口实现特定的功能,我希望该函数与continuation异步运行(我希望这些实现是I/O绑定的并且想要确保所有客户端对象尽快完成此功能).我正在使用Visual Studio异步CTP刷新SP1,C#"5.0".

在抽象类的子对象中强制执行异步行为的推荐做法是什么(见下文)?我不能(显然)使用虚方法方法强制使用'异步'方法.我只能要求'任务'返回类型.这是否意味着我不应该尝试在子对象中完全要求异步行为?在这种情况下,返回类型应该简单地"无效"吗?

公共接口现在是系统设计的一个不幸后果,但这是一个单独的问题.显然,我无法限制任何人绕过'BaseFoo'并实现'IFoo'接口的异步.

这是代码:

public interface IFoo
{
    void Bar(); //NOTE: Cannot use 'async' on methods without bodies.
}

public abstract class BaseFoo : IFoo
{
    public async void Bar()
    {
        await OnBar(); //QUESTION: What is the right "async delegation" pattern?
    }

    protected virtual async Task OnBar()
    {
        await TaskEx.Yield();
    }
}

public class RealFoo : BaseFoo //NOTE: May be implemented by 3rd party
{
    protected override async Task OnBar()
    {
        //CLIENT: Do work, potentially awaiting async calls

        await TaskEx.Yield(); //SECONDARY QUESTION: Is there a way to avoid this if there are no 'awaits' in the client's work?
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 84

是否使用async/ await不实现方法是实现细节.方法应该如何表现的是合同细节,应该以正常方式指定.

请注意,如果您使方法返回a Task或a Task<T>,则更明显的是它意味着异步,并且可能很难在异步的情况实现.

另一方面,如果有一个实现(例如用于测试目的)await表达式永远不会完整,那么为什么要强制某人编写异步方法而不进行任何await调用呢?您期望实现受IO限制,但可能会出现特殊情况,其中实现需要使用硬编码数据等.

基本上你必须在方法的文档中处理这个 - 如果你不能相信实现者阅读它,你无论如何都没有机会:(

  • @Lars:我很想在任何地方使用`Task`返回类型而不是`void` - 大多数都是`void`,这样你就可以用异步方法实现事件处理程序.能够等待异步方法完成等等通常很方便 - 而且`Task`使这很容易. (8认同)

dav*_*v_i 16

除了Jon的答案之外,如果您遵循基于任务的异步模式,那么您的方法名称应该加上后缀Async,哪些自我文档它是一个异步方法.

如果您正在实现一个接口

public interface IFoo
{
    Task BarAsync();
}
Run Code Online (Sandbox Code Playgroud)

很明显,这应该用async关键字来实现.