Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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#_Async Await - Fatal编程技术网

C# 为什么在同一行上调用方法和等待它被认为是异步的?

C# 为什么在同一行上调用方法和等待它被认为是异步的?,c#,async-await,C#,Async Await,为了更好地理解async/await,我正在查看上的示例,但以下内容让我感到困惑: 我理解为什么下面的示例被认为是异步的。调用HandleFileAsync,调用Console.WriteLine,然后等待任务完成后再继续 static async void ProcessDataAsync() { // Start the HandleFile method. Task<int> task = HandleFileAsync("C:\\enable1.txt")

为了更好地理解async/await,我正在查看上的示例,但以下内容让我感到困惑:

我理解为什么下面的示例被认为是异步的。调用HandleFileAsync,调用Console.WriteLine,然后等待任务完成后再继续

static async void ProcessDataAsync()
{
     // Start the HandleFile method.
     Task<int> task = HandleFileAsync("C:\\enable1.txt");

     // Control returns here before HandleFileAsync returns.
     // ... Prompt the user.
     Console.WriteLine("Please wait patiently " +
         "while I do something important.");

     // Wait for the HandleFile task to complete.
     // ... Display its results.
     int x = await task;
     Console.WriteLine("Count: " + x);
}
那么,如果我们正在等待Task.Run的完成,那么异步运行到底发生了什么?我认为,当我们等待后续任务的执行完成时,它会变成一个阻塞调用,在本例中,它是在同一行上调用的

我错过了什么

我认为,当我们等待后续任务的执行完成时,它会变成一个阻塞调用,在本例中,它是在同一行上调用的。我错过了什么

你的信仰是错误的;这就是你所缺少的。“wait”的意思是“现在返回,在异步等待时运行其他程序,当结果可用时,返回此处。”

获取任务的结果做您认为等待做的事情。如果它所做的只是同步地获取任务的结果,我们就不必等待!它异步获取任务的结果

在我们讨论这个问题时,这个评论是错误的:

// Control returns here before HandleFileAsync returns.
这怎么可能呢HandleFileAsync返回了一个任务如果HandleFileAsync没有返回,控制如何在手头有任务的情况下到达该点?当然它回来了

这一评论具有误导性:

// Wait for the HandleFile task to complete.
这应该是异步等待任务完成。记住,异步等待的意思是“现在返回,运行更多的工作,当任务完成后,在这一点上继续,结果在手。”


如果我是你,我会找到更好的教程

什么是异步发生的?
考虑这一点:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static volatile uint i;
        static uint Test()
        {
            Thread.Sleep(1000);
            i = 2; //uint.MaxValue;
            while (i-- > 0) { }
            return i;
        }

        static bool done;
        static async void Example()
        {
            var t = await Task.Run(() => Test());
            Console.WriteLine("result: " + t);
            done = true;
        }
        static void Main(string[] args)
        {
            Example();
            Console.WriteLine("wait: Control returns here before Example() returns ");
            while (!done) { }
            Console.WriteLine("done ");
        }
    }
}
Example()本身是异步发生的。
因此,如果您在(!done){}

程序在
Example()
完成之前退出。

我希望这会有所帮助。

HandleFileAsync
在您等待它结束之前不会被调用,因此您的代码片段在异步功能方面基本相同。您只需将指针指向顶部的任务。但是,我相信您误解了
async
的功能。它只是在不阻塞主上下文线程(或GUI应用程序的UI线程)方面是异步的。代码仍将按顺序运行,逐行-
HandleFileAsync
不会与
ProcessDataAsync
中的其余代码并行运行@Rob:根本不会
HandleFileAsync
是在
ProcessDataAsync
@bulletblue的第一行调用的:我同意Eric Lippert的观点,dotnetperls教程令人困惑,有些误导。我有一个可能对你有帮助的方法。@StephenCleary如果行
Task Task=HandleFileAsync(…)
运行但任务从未等待,那么预期的行为是什么?是否执行了HandleFileAsync,但我们从未得到结果?因此,如果我们不关心结果,而只关心执行情况,我们可以选择不等待?@Howiecamp:大多数时候,“开火并忘记”是一个错误。你确定你不在乎结果吗?你不需要知道它是否失败了?(将在任务上放置异常,您的代码将忽略该异常)。您不需要知道它何时完成,所以您的代码知道退出程序是安全的?
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static volatile uint i;
        static uint Test()
        {
            Thread.Sleep(1000);
            i = 2; //uint.MaxValue;
            while (i-- > 0) { }
            return i;
        }

        static bool done;
        static async void Example()
        {
            var t = await Task.Run(() => Test());
            Console.WriteLine("result: " + t);
            done = true;
        }
        static void Main(string[] args)
        {
            Example();
            Console.WriteLine("wait: Control returns here before Example() returns ");
            while (!done) { }
            Console.WriteLine("done ");
        }
    }
}