c# - 为什么 Interlocked.Exchange 触发警告 CS4014?

标签 c# visual-studio-2013 task-parallel-library compiler-warnings

以下简化示例会生成此编译器警告:

warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

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;
    }
}

所以简单地将结果分配给局部变量就足够了。

最佳答案

您正在调用 generic overload Interlocked.Exchange:

public static T Exchange<T>(ref T location1, T value)
    where T : class

这意味着调用的结果是一个任务。警告按设计工作。它发现您正在调用一个返回 Task 的函数,因此可能是异步的,但您不会等待它的结果。

行:

Interlocked.Exchange(ref _Task, null);

含义如下:

  • _Task 中的内容替换为 null
  • 抛出之前的值(给你作为Interlocked.Exchange的返回值)

下面一行:

await _Task;

很可能相当于:

await null;

而且会繁荣

我说最有可能,因为极有可能另一个线程将某些内容写入_Task,而您将等待

我想你真正想写的代码如下:

public async Task DoSomething()
{
    var task = Interlocked.Exchange(ref _Task, null);

    if (task != null)
        await task;
}

或者,对于 .NET 4.6:

public async Task DoSomething()
    => await (Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask);

你甚至可以去掉 async:

public Task DoSomething()
    => Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask;

关于c# - 为什么 Interlocked.Exchange 触发警告 CS4014?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35417106/

相关文章:

c# - 使用 NLog 输出到两个日志文件之一

c# - Visual Studio 2013 中 C# 调用堆栈中的未知函数

c# - 从 Visual Studio 打开的 CMD 提示不会在我的计算机上启动 exe。为什么不?

c# - 使用 Parallel.For 时出现不可预测的结果

c# - 了解 COM c# 接口(interface)

c# - 无法将字符串解析为整数值

c# - Asp.Net 结合 C# 和 Angular

sql-server - 无法在 Visual Studio 2012 或 2013 中打开 SSIS 项目(迁移失败)

c# - 在任务中捕获异常的最佳方法是什么?

c# - 异步操作中的依赖关系和执行顺序