2015-04-28 47 views
25

我有一个接口,公开一些异步方法。更具体地说,它定义了返回任务或任务<T>的方法。我正在使用async/await关键字。我应该担心“这种异步方法缺乏'等待'运营商,并将同步运行”警告

我正在实现这个接口的过程。但是,在这些方法中的一些方法中,没有什么可以等待。出于这个原因,我得到了编译器警告“这种异步方法缺乏'等待'运营商,并将同步运行...”

我明白为什么我得到的错误,但我想知道我是否应该对他们做任何事情在这上下文。忽略编译器警告感觉不对。

我知道我可以通过在Task.Run上等待来解决它,但是对于只做一些廉价操作的方法感觉不对。这听起来像会增加不必要的执行开销,但是我也不确定是否已经存在,因为存在async关键字。

我应该忽略警告还是有办法解决这个问题我没有看到?

+2

这将取决于具体情况。你确定你想要这些操作同步执行吗?如果您确实希望它们同步执行,为什么该方法标记为“异步”? – Servy

+8

只需删除'async'关键字即可。你仍然可以使用Task.FromResult返回一个Task。 –

+0

在一个例子中,它确实只是给属性分配了一些值,所以我非常适合同步执行它。关于如何处理编译器的警告更具体一些,似乎可能是明显的删除异步关键字 – dannykay1710

回答

42

async关键字仅仅是方法的实现细节;它不是方法签名的一部分。如果一个特定的方法实现或超越无关,等待,然后就省略异步关键字,并返回一个完成的任务使用Task.FromResult<TResult>

public Task<string> Foo()    // public async Task<string> Foo() 
{          // { 
    Baz();        //  Baz(); 
    return Task.FromResult("Hello"); //  return "Hello"; 
}          // } 

如果你的方法返回Task代替Task<TResult>,那么你就可以返回一个完成任何类型和价值的任务。 Task.FromResult(0)似乎是一个普遍的选择:

public Task Bar()      // public async Task Bar() 
{          // { 
    Baz();        //  Baz(); 
    return Task.FromResult(0);   // 
}          // } 

或者,如.NET框架4.6的,你可以返回Task.CompletedTask

public Task Bar()      // public async Task Bar() 
{          // { 
    Baz();        //  Baz(); 
    return Task.CompletedTask;   // 
}          // } 
+0

谢谢我认为我错过的一点是创建已完成的任务的概念,而不是返回像您说的那样的具有async关键字的实际任务。看起来很明显,但我只是没有看到它! – dannykay1710

+1

任务可以使用静态成员沿着Task.Empty的这一行进行。意图会更清楚一点,我很难想象所有这些尽职尽责的任务都会返回一个从不需要的零。 –

+0

'await Task.FromResult(0)'?怎么样'等待Task.Yield()'? – Sushi271

3

一些“异步”操作完成同步完成是合理的,但为了多态性仍符合异步调用模型。

一个真实的例子是OS I/O API。某些设备上的异步和重叠调用总是以内联方式完成(例如,写入使用共享内存实现的管道)。但是他们实现了与在后台继续执行的多部分操作相同的界面。