以下简化示例生成此编译器警告:
警告CS4014:由于未等待此呼叫,因此在呼叫完成之前将继续执行当前方法。考虑应用“等待”#39;运算符到调用的结果。
public class TaskInterlockedExchangeTest
{
private Task _Task;
public async Task DoSomething()
{
Interlocked.Exchange(ref _Task, null);
await _Task;
}
}
警告在Interlocked.Exchange
电话的线路上引发。据我所知Interlocked.Exchange
不是async
所以为什么编译器会触发此警告呢?现在这对我没有任何意义,所以我错过了什么?
我们会将警告视为错误,因此我试图弄清楚如何解决这个问题(除了禁用有关违规代码的警告,我只会将其视为最后的手段)。
这发生在VS2013(更新5)上。
更新
我刚刚发现以下内容避免了警告:
public class TaskInterlockedExchangeTest
{
private Task _Task;
public async Task DoSomething()
{
var t = Interlocked.Exchange(ref _Task, null);
await _Task;
}
}
所以简单地将结果分配给局部变量就足够了。
答案 0 :(得分:6)
您正在调用Interlocked.Exchange
的{{3}}:
public static T Exchange<T>(ref T location1, T value)
where T : class
这意味着通话的结果是Task
。警告按设计工作。它会看到您正在调用一个返回Task
的函数,因此可能是异步的,但您不会await
其结果。
该行:
Interlocked.Exchange(ref _Task, null);
表示以下内容:
_Task
中的内容
null
的返回值以下一行:
Interlocked.Exchange
最有可能相当于:
await _Task;
并将热潮。
我说很可能是,因为其他线程在await null;
中写了一些内容的可能性微乎其微,而且你要去_Task
那个。{ / p>
我想您想写的真实代码如下:
await
或者,使用.NET 4.6:
public async Task DoSomething()
{
var task = Interlocked.Exchange(ref _Task, null);
if (task != null)
await task;
}
你甚至可以摆脱public async Task DoSomething()
=> await (Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask);
:
async