当前位置: 首页 > 编程语言 > C#

看不懂Async和Await分享

时间:2023-04-10 22:07:31 C#

看不懂Async和Await,我还是失败了。我希望有人能帮助回答这些稍微抽象的问题,以帮助我的大脑。1.当async/await自己的async关键字什么都不做并且await关键字添加了一个暂停点时,为什么他们说async/await启用“异步”方法?在不添加暂停点的情况下,该方法被强制同步动作,即完成await标记的任务,然后再继续。2.显然你不应该使用asyncvoid除了事件处理程序,那么你通常如何调用异步方法?似乎为了使用await关键字调用异步方法,调用自身的方法/类需要标记为异步。我见过的所有示例都使用事件处理程序“启动”了一个asyncvoid方法。您将如何“逃避”异步/等待的包装以运行该方法?3.publicasyncTaskSaveScreenshot(stringfilename,IWebDriverdriver){varscreenshot=driver.TakeScreenshot();awaitTask.Run(()=>{Thread.Sleep(2000);screenshot.SaveAsFile(filename,ScreenshotImageFormat.Bmp);Console.WriteLine("屏幕截图已保存");});Console.WriteLine("方法结束");}回到1。这看起来像一个同步方法。执行在到达Task.Run时暂停,因此Console.WriteLine("Endofmethod");在任务完成之前不会执行。也许整个方法本身会在代码中触发时异步执行?但是回到2,你需要await来调用它,否则你会得到消息'因为没有等待这个调用..'所以添加await将导致该执行点同步等等。任何有助于理解这一点的帮助将不胜感激。在不添加暂停点的情况下,该方法被强制同步动作,即完成await标记的任务,然后再继续。不,您想到的词是“顺序”,而不是“同步”。在异步顺序代码中等待结果。“顺序”是指“一次一个”;“同步”意味着“阻塞直到完成”。你通常如何调用异步方法?使用等待。您将如何“逃避”异步/等待的包装以运行该方法?理想情况下,您没有.你总是异步的。现代框架(包括ASP.NETMVC、AzureFunctions/WebJobs、NUnit/xUnit/MSTest等)都允许您有一个返回任务的入口点。不太现代的框架(包括WinForms、WPF、XamarinForms、ASP.NETWebForms等)都允许asyncvoid入口点。所以理想情况下,您不要从同步代码中调用异步代码。如果您考虑异步代码是什么,这是有道理的:它的全部意义在于不阻塞调用线程,因此如果您阻塞异步代码上的调用线程,您首先会失去异步代码的所有好处。也就是说,在极少数情况下您需要同步处理代码。例如,如果您正处于转换为异步的过程中,或者您被强制代码同步的库/框架所束缚并且不能使用asyncvoid。在这种情况下,您可以使用我的文章brownasync中的技巧。你的理解很好:)。您似乎缺少的要点是.NET中的“异步”方法意味着停止执行而不阻塞调用线程的方法。正如您在(1)中指出的,async关键字基本上允许await并要求返回类型为void或Task/Task。await只是指示当前方法暂停执行,直到任务完成。您在这里缺少的是它仅暂停当前方法。它不会阻塞方法执行的线程。这在WPF应用程序的UI线程等情况下很重要。方法执行被挂起,一切继续运行,线程被阻塞,应用程序停止响应。您通常希望异步调用一直到顶部(如事件处理程序),这允许最大的灵活性并防止死锁情况。然而;您可以等待任务返回方法完成Wait:someAsyncMethod.Wait()或者获取返回值:varresult=someAsyncMethod.Result;请注意,这两者都是同步的,并且会阻塞调用线程。如果异步任务正在等待调用线程上的某些其他工作完成,那么这样做可能会导致死锁。以上应该回答你在(3)中的问题;该方法本身似乎是同步执行的(这是await/async的魔力),但任务不会阻塞调用线程。它是异步的,因为您不必等待方法返回。在您的代码中,您可以调用异步方法并将任务保存在变量中。继续做其他事情。之后,当需要方法结果时,等待响应(任务)。以上就是C#学习教程:看不懂异步和等待的全部内容分享。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——//同步方法。staticvoidMain(string[]args){//调用异步方法,但在需要时不要等待它们。任务task1=DoAsync();任务task2=DoAsync();任务task3=DoAsync();//做其他事情。//现在,是时候等待异步方法完成了。Task.WaitAll(task1,task2,task3);//对结果做一些事情。Console.WriteLine(task1.Result);控制台.ReadKey();}privatestaticasyncTaskDoAsync(){Console.WriteLine("Started");等待任务。延迟(3000);Console.WriteLine("完成");返回“成功”;}//输出://Started//Started//Started//Finished//Finished//Finished//Success本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: