Chr*_*Wue 2 c# compiler-warnings task-parallel-library visual-studio-2013
以下简化示例生成此编译器警告:
警告CS4014:由于未等待此调用,因此在完成调用之前,将继续执行当前方法.考虑将'await'运算符应用于调用的结果.
public class TaskInterlockedExchangeTest
{
private Task _Task;
public async Task DoSomething()
{
Interlocked.Exchange(ref _Task, null);
await _Task;
}
}
Run Code Online (Sandbox Code Playgroud)
通过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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,简单地将结果分配给局部变量就足够了.
我们在调用泛型重载的Interlocked.Exchange
:
public static T Exchange<T>(ref T location1, T value)
where T : class
Run Code Online (Sandbox Code Playgroud)
这意味着通话的结果是a Task
.警告按设计工作.它看到你正在调用一个返回a的函数Task
,因此可能是异步的,但你不是await
它的结果.
这条线:
Interlocked.Exchange(ref _Task, null);
Run Code Online (Sandbox Code Playgroud)
意味着以下内容:
_Task
与null
Interlocked.Exchange
)以下行:
await _Task;
Run Code Online (Sandbox Code Playgroud)
最有可能相当于:
await null;
Run Code Online (Sandbox Code Playgroud)
并将蓬勃发展.
我最有可能说,因为有一个很小的可能性,另一个线程写了一些东西_Task
,你会去await
那.
我想你要编写的真实代码如下:
public async Task DoSomething()
{
var task = Interlocked.Exchange(ref _Task, null);
if (task != null)
await task;
}
Run Code Online (Sandbox Code Playgroud)
或者,使用.NET 4.6:
public async Task DoSomething()
=> await (Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask);
Run Code Online (Sandbox Code Playgroud)
你甚至可以摆脱async
:
public Task DoSomething()
=> Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask;
Run Code Online (Sandbox Code Playgroud)