Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么是联锁的。交换触发警告CS4014?_C#_Visual Studio 2013_Task Parallel Library_Compiler Warnings - Fatal编程技术网

C# 为什么是联锁的。交换触发警告CS4014?

C# 为什么是联锁的。交换触发警告CS4014?,c#,visual-studio-2013,task-parallel-library,compiler-warnings,C#,Visual Studio 2013,Task Parallel Library,Compiler Warnings,以下简化示例生成此编译器警告: 警告CS4014:由于未等待此调用,因此当前方法的执行将在调用完成之前继续。考虑将“Acess”运算符应用到调用的结果。< /P> 在联锁的线路上发出警告。交换呼叫。就我所知,它不是async,那么编译器究竟为什么会触发这个警告呢?现在这对我来说没有任何意义,那么我错过了什么呢 我们确实将警告视为错误,因此我试图找出如何解决此问题(除了禁用针对违规代码的警告,我将其视为最后手段) 这发生在VS2013上(更新5) 更新 我刚刚发现以下内容避免了警告: public

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

警告CS4014:由于未等待此调用,因此当前方法的执行将在调用完成之前继续。考虑将“Acess”运算符应用到调用的结果。< /P> 在
联锁的线路上发出警告。交换
呼叫。就我所知,它不是
async
,那么编译器究竟为什么会触发这个警告呢?现在这对我来说没有任何意义,那么我错过了什么呢

我们确实将警告视为错误,因此我试图找出如何解决此问题(除了禁用针对违规代码的警告,我将其视为最后手段)

这发生在VS2013上(更新5)

更新

我刚刚发现以下内容避免了警告:

public class TaskInterlockedExchangeTest
{
    private Task _Task;

    public async Task DoSomething()
    {
        var t = Interlocked.Exchange(ref _Task, null);
        await _Task;
    }
}
因此,只需将结果赋给局部变量就足够了。

您正在调用的是
Interlocked.Exchange的函数:

public static T Exchange<T>(ref T location1, T value)
    where T : class
指以下各项:

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

    if (task != null)
        await task;
}
  • \u任务中的内容替换为
    null
  • 抛出上一个值(作为
    Interlocked.Exchange
    的返回值提供给您)
以下一行:

await _Task;
很可能相当于:

await null;
而且会爆炸

我说的很有可能,因为有一个很小的可能性,另一个线程在
\u 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;

Exchange返回任务,请尝试调用另一个从
async
方法返回任务的方法,可能会出现相同的警告。您忽略了
Interlocked
的返回值,它是
任务
。停止忽略它,警告就会消失:)另外,您(很可能)正在等待
null
。。。您可能是指
var task=Interlocked.Exchange(ref\u task,null);如果(task!=null)等待任务@Luaan提醒自己:永远要学究气,所以:-)我“修正”了上面的评论;)@Lucastzesniewski:这只是一个再现警告的最小示例,而不是实际的生产代码。我知道在这个示例中,
\u Task
null
。这是复制警告所需的最小代码。嗯,我明白了。因此,一个方法返回的
Task
被认为是潜在的异步(即使没有关于Interlocked.Exchange是异步的)就足够了。无论如何,只需将返回值赋给局部变量(而不实际使用它)就可以避免出现警告。@ChrisWue完全正确。但我想说,当应用于泛型返回类型时,这种逻辑是有争议的,正如您的示例所示。@Lucastzesniewski我同意,所以我创建了。
public Task DoSomething()
    => Interlocked.Exchange(ref _Task, null) ?? Task.CompletedTask;