async不应该用于高CPU任务?我想知道async是否正确-await不应该用于“高CPU”任务。我在演示文稿中看到了这一点。所以我猜这意味着什么TaskcalculateMillionthPrimeNumber=CalculateMillionthPrimeNumberAsync();做独立工作();intp=awaitcalculateMillionthPrimeNumber;我的问题是,以上是否有意义,或者如果没有,是否还有其他一些使高CPU任务异步的示例?我想知道async-await是否应该用于“高CPU”任务。是的,这是真的。我的问题是上述情况是否有意义我会说它没有意义。通常,您应该避免使用Task.Run来实现具有异步签名的方法。不要为同步方法公开异步包装器。这是为了防止消费者混淆,尤其是在ASP.NET上。但是,使用Task.Run调用同步方法并没有错(例如,在UI应用程序中)。通过这种方式,您可以使用多线程(Task.Run)来保持UI线程空闲并等待优雅地使用它:vartask=Task.Run(()=>CalculateMillionthPrimeNumber());做独立工作();varprime=等待任务;事实上,async/await有两个主要用途。一个(据我所知是将其放入框架的主要原因之一)是让调用线程在等待结果的同时做其他工作。这主要用于I/O绑定任务(即主要“持有”是某种I/O的任务——等待硬盘驱动器、服务器、打印机等响应或完成它们的任务)。作为旁注,如果您以这种方式使用async/await,请务必确保您已实现它,以便调用线程在等待结果时实际上可以做其他工作;我见过很多人做“A等待B,等待C”的事情;这最终可能不会比A同步调用B和B同步调用C更好(因为调用线程在等待B和C的结果时永远不允许做其他工作)。在I/O绑定任务的情况下,创建额外的线程只是为了等待结果是没有意义的。我通常的类比是想在一家有10个人的餐厅点菜。如果服务员要求点的第一个人还没准备好,服务员不会等他准备好了再接其他人的订单,也不会带第二个服务员来等第一个人。在这种情况下,最好的办法是询问组中的其他9个人的订单;希望在他们点餐时,第一个人已经准备就绪。如果没有,至少服务员还是节省了一些时间,因为他闲着的时间少了。您还可以使用Task.Run类的Task.Run来执行CPU绑定任务(这是我第二次使用它)。按照我们上面的类比,在这种情况下,通常有更多的服务员是有用的——例如,如果一个服务员有太多的桌子无法服务。真的,这实际上都是使用线程池的“幕后”;它是进行CPU绑定工作的几种可能构造之一(例如,只是将其“直接”放在线程池上,显式创建一个新线程,或使用后台工作程序),因此最终使用哪种机制是一个设计问题。async/await的一个优点是它可以(在适当的情况下)减少您必须手动编写的显式锁定/同步逻辑的数量。这是一个愚蠢的例子:privatestaticasyncTaskSomeCPUBoundTask(){//在此处插入实际的CPU绑定任务usingTask.RunawaitTask.Delay(100);}publicstaticasyncTaskQueueCPUBoundTasks(){列表任务=newList();//排队你想要的许多CPU绑定任务(inti=0;i显然,我在这里假设任务是完全可并行的。另请注意,你可以在这里自己使用线程池,但那将是有点不方便,因为您需要一些方法来自己弄清楚是否所有这些都已完成(而不是让框架为您弄清楚)。您还可以在此处使用Parallel.For循环。假设您的CalculateMillionthPrimeNumber如下所示(使用goto时非常有效或理想,但非常简单):publicintCalculateMillionthPrimeNumber(){Listprimes=newList(1000000){2};整数=3;while(primes.Count现在,这里异步做事没有用。让我们使用异步使其成为任务返回方法:publicasyncTaskCalculateMillionthPrimeNumberAsync(){Listprimes=newList(1000000){2};intnum=3;while(primes。Count编译器会警告我们,因为我们无处等待任何有用的东西。实际上调用它与调用Task.FromResult(CalculateMillionthPrimeNumber())是一样的,一个稍微复杂的版本。也就是说,它与做计算,然后用计算出的数字作为结果创建一个完成的任务。现在,完成的任务并不总是没有意义的。例如,考虑:);return_cachedInterestingString;}这会在字符串在缓存中时返回完成的任务,否则返回的速度非常快。其他情况是如果有多个实现,并不是所有的实现都可以使用异步I/O.此外,此方法的异步方法await将返回已完成的任务,具体取决于此。这其实是一个很好的做法,保持同一个线程就行,该干什么干什么就干什么。但如果它总是可能的,那么唯一的影响就是创建Task对象和async用来实现它的状态机。所以,毫无意义。如果这就是您问题中的版本的实现方式,那么calculateMillionthPrimeNumber将使IsCompleted从一开始就返回true。您应该刚刚调用了非异步版本。好的,作为CalculateMillionthPrimeNumberAsync()的实现者,我们想为我们的用户做一些更有用的事情。所以我们这样做:好的,现在我们不浪费用户的时间了。DoIndependentWork()将与CalculateMillionthPrimeNumberAsync()一起使用,如果它先完成,则await将释放线程。大的!只是,我们实际上还没有将指针从同步位置移开。事实上,特别是如果DoIndependentWork()不是非常费力的话,我们可以让它变得更糟。同步方式将在一个线程上执行所有操作,我们称之为线程A。新方法在线程B上执行计算,然后释放线程A,然后以多种可能的方式进行同步。这是很多工作,有回报吗?嗯,也许吧,但是CalculateMillionthPrimeNumberAsync()的作者无从知晓,因为影响它的因素都在调用代码中。调用代码本身可以做StartNew,更能满足同步选项的需要。因此,虽然一个任务可以作为与另一个任务并行调用CPU绑定代码的便捷方式,但这并不是一种实用的方法。更糟糕的是他们作弊,因为看到CalculateMillionthPrimeNumberAsync的人可能会认为调用它并非毫无意义。除非CalculateMillionthPrimeNumberAsync本身一直在使用异步/等待,否则没有理由不让Task运行繁重的CPU工作,因为它只是将您的方法委托给ThreadPool的线程。什么是ThreadPool线程,它和普通线程的区别就在这里。简而言之,它只是让线程池线程保持一定的时间(并且线程池线程的数量是有限的),所以除非你占用太多线程,否则没有什么可担心的。以上是C#学习教程:高CPU任务不应该用async吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
