Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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# 异步警告令我困惑_C#_Asynchronous_Warnings - Fatal编程技术网

C# 异步警告令我困惑

C# 异步警告令我困惑,c#,asynchronous,warnings,C#,Asynchronous,Warnings,这不是一个调试类型的问题,我只是想在非同步编程领域寻找一点具体的教育,我承认我在这个领域并不熟悉 我正在编写一个程序,我需要它在执行其他功能的同时定期进行调用。我查阅了如何编写一个异步方法来实现这一点,并实际实现了它 让我困惑的是,当我从主方法调用它时,我收到一条警告,说我应该使用wait关键字让程序等待方法调用完成,否则我可能无法获得预期的行为,这对我来说很奇怪。我认为,编写一个异步方法的关键是让它运行,然后在不等待它完成的情况下继续前进,因此注意这个警告将无法达到目的。另一方面,我并没有自大

这不是一个调试类型的问题,我只是想在非同步编程领域寻找一点具体的教育,我承认我在这个领域并不熟悉

我正在编写一个程序,我需要它在执行其他功能的同时定期进行调用。我查阅了如何编写一个异步方法来实现这一点,并实际实现了它

让我困惑的是,当我从主方法调用它时,我收到一条警告,说我应该使用wait关键字让程序等待方法调用完成,否则我可能无法获得预期的行为,这对我来说很奇怪。我认为,编写一个异步方法的关键是让它运行,然后在不等待它完成的情况下继续前进,因此注意这个警告将无法达到目的。另一方面,我并没有自大到认为我比开发VisualStudio并添加警告的专业人员更了解,所以肯定有更多情况下添加wait关键字更有意义

我的问题是:通常如何使用异步方法来保证注意这个警告

编辑:人们请求的代码和警告的特定文本,因此:

异步方法:

public static async Task FindPairs(TimeSpan interval, CancellationToken cancellationToken)
            {
            while (true)
                {
                lock (relevantVariable)
                    {
                    doStuffEveryInterval();
                    }
                await Task.Delay(interval, cancellationToken);
                }
            }
警告如下:由于此调用未被等待,因此当前方法的执行将在调用完成之前继续。考虑将“等待”操作符应用到调用的结果。当前方法调用一个异步方法,该方法返回一个或多个任务,并且不对结果应用wait运算符。对async方法的调用启动异步任务。但是,由于未应用等待运算符,程序将继续,而不等待任务完成。在大多数情况下,这种行为并不是你所期望的。通常,调用方法的其他方面取决于调用的结果,或者至少在您从包含调用的方法返回之前,被调用的方法应该完成

一个同样重要的问题是,在被调用的异步方法中引发的异常会发生什么情况。在返回一个或多个任务的方法中引发的异常存储在返回的任务中。如果您没有等待任务或明确检查异常,则异常将丢失。如果您等待该任务,它的异常是rethrown

作为最佳实践,您应该始终等待电话

只有当您确信不希望等待异步调用完成并且调用方法不会引发任何异常时,才应该考虑抑制警告。在这种情况下,可以通过将调用的任务结果指定给变量来抑制警告。”

我认为,编写异步方法的关键是让它运行,然后不必等待它完成就可以继续

如果你相信的话,那么你为什么要等待
延迟
延迟
返回一个任务;
延迟
返回一个任务;你开始了这个任务,你肯定想在它完成之前继续,然后再做下一个循环迭代

当然不是。如果它异步运行并在没有人等待的情况下完成,那么这将破坏整个延迟点

那么,
等待
到底是什么意思呢?它的意思是:异步等待。也就是说:此工作流在任务完成之前无法继续,因此如果任务未完成,请查找其他要做的工作,稍后再回来

这就是为什么异步方法的调用方通常会等待结果的原因。调用方异步调用您是因为他们认为工作流需要一些时间才能完成,并且他们可以让调用方在异步等待方法完成时做更多的工作

这是您通常会做的,但您的方法不正常。您的方法永远不会正常完成!如果您执行了
等待
此方法,您将等待它抛出(因为它被取消),而不是等待它正常完成,因为它不会正常完成

因此,方法返回的任务的
wait
实际上可能是永远等待,这不是您想要的

因此,在这种情况下,您可以忽略或抑制警告。但是在正常情况下,您调用某个方法是因为您想要它的副作用或结果,并且在得到它之前您无法继续您的工作流。因此,您可以等待任务,以便您的调用方可以在等待过程中做更多的工作或您的被叫人的工作流来完成

在编写更多异步代码之前,请确保绝对清楚。
wait
是异步工作流上的排序操作。
它意味着“在完成此任务之前,此工作流不会继续;在你等待的时候找点别的事做,等我们可以继续的时候再来。”

将其与对普通方法的“普通”调用进行比较。
x=foo();
表示“在对
foo
的调用完成之前,此工作流不会继续;除了运行
foo
直到完成之外,什么也不做。我们习惯于调用同步,等待结果,以至于我们不再去想它


这个问题指出了C#型系统的一个更大的设计问题。非通用的
任务
在逻辑上是“异步的”"; 也就是说,工作流已完成,但未使用值完成C#对于永远不会正常返回但可能抛出的方法,没有类型系统概念。您可以想象一个特殊版本的
void
,可能是
void never
,在这种方法中返回或具有可到达的端点是错误的

您的工作流在逻辑上是一个“从不任务”——它是一个不正常完成的异步工作流。