6

我很高兴能用 C#5.0 创建我的第一个应用程序,我想使用 async/await 关键字来减轻异步数据调用的痛苦。

我有点困惑,接口不允许 async 关键字成为合同的一部分,因为 await 关键字仅适用于 async 标记的方法。这意味着不可能通过接口引用调用异步方法。这也适用于抽象方法。我在这里错过了什么吗?这意味着我的常规 DI-stuff 将不再起作用:

IAsyncRepository<T> {
 Task<IList<T>> GetAsync(); // no 'async' allowed
}

abstract class AsyncRepositoryBase<T> {
 public abstract Task<IList<T>> GetAsync(); // no 'async' allowed

// 客户端代码:

IAsyncRepository<Model> repo = ioc.Resolve<IAsyncRepository<Model>>();
var items = await repo.GetAsync(); // DOOOOOH, will not compile!

这是我目前的解决方案:

public abstract class AsyncRepositoryBase<T>
{
    protected Task<IList<T>> _fetcherTask;

    protected AsyncRepositoryBase(Task<IList<T>> fetcherTask)
    {
        _fetcherTask = fetcherTask;
    }

    public virtual async Task<IList<T>> GetASync()
    {
        return await _fetcherTask;
    }
}

我必须在抽象和语言功能之间做出选择吗?请告诉我我错过了什么。

4

1 回答 1

7

await 关键字仅适用于异步标记的方法

有你的问题。虽然await必须方法内部async,但它可以等待任何任务,无论是否通过实现async

例如:

interface IFoo {
    Task BarAsync();
}

class Foo : IFoo {
    public async Task BarAsync() {
        // Implemented via async/await in this case.
        // You could also have implemented it without async/await.
    }
}

// ...

async void Test() {
    IFoo foo = ... ;
    await foo.BarAsync(); // Works no matter how BarAsync is implemented.
}

至于您的语法错误:await repo.GetAsync(); // DOOOOOH, will not compile!-您是否忘记将包含这段代码的方法标记为async(您不必将其标记IAsyncRepository.GetAsyncasync)?

于 2012-10-22T23:58:52.133 回答