关于线程以及异步方法在C#中是否真正异步的困惑 [英] Confusion regarding threads and if asynchronous methods are truly asynchronous in C#

查看:263
本文介绍了关于线程以及异步方法在C#中是否真正异步的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读异步/等待以及何时Task.Yield可能有用并且遇到

I was reading up on async/await and when Task.Yield might be useful and came across this post. I had a question regarding the below from that post:

当您使用异步/等待时,无法保证您使用的方法 您在等待时调用FooAsync()实际上将异步运行. 内部实现可以自由地使用完全返回 同步路径.

When you use async/await, there is no guarantee that the method you call when you do await FooAsync() will actually run asynchronously. The internal implementation is free to return using a completely synchronous path.

这对我来说还不太清楚,可能是因为我脑海中对异步的定义并不统一.

This is a little unclear to me probably because the definition of asynchronous in my head is not lining up.

在我看来,由于我主要从事UI开发,因此异步代码不是在UI线程上运行,而是在其他线程上运行的代码.我想在我引用的文字中,如果某个方法在任何线程上阻塞(即使是例如线程池线程),它也不是真正异步的.

In my mind, since I do mainly UI dev, async code is code that does not run on the UI thread, but on some other thread. I guess in the text I quoted, a method is not truly async if it blocks on any thread (even if it's a thread pool thread for example).

问题:

如果我有一个长时间运行的任务,该任务受CPU限制(比如说它在做大量困难的数学运算),那么异步运行该任务必须阻塞某些线程,对吗?实际需要做一些数学运算.如果我等待它,那么某些线程将被阻塞.

If I have a long running task that is CPU bound (let's say it is doing a lot of hard math), then running that task asynchronously must be blocking some thread right? Something has to actually do the math. If I await it then some thread is getting blocked.

什么是真正异步方法的示例,它们如何实际工作?是否仅限于那些利用某些硬件功能的I/O操作,从而不会阻塞任何线程?

What is an example of a truly asynchronous method and how would they actually work? Are those limited to I/O operations which take advantage of some hardware capabilities so no thread is ever blocked?

推荐答案

这对我来说还不太清楚,可能是因为我脑海中对异步的定义并不统一.

This is a little unclear to me probably because the definition of asynchronous in my head is not lining up.

请您澄清一下.

在我看来,由于我主要从事UI开发,因此异步代码不是在UI线程上运行,而是在其他线程上运行的代码.

In my mind, since I do mainly UI dev, async code is code that does not run on the UI thread, but on some other thread.

这种信念很普遍,但却是错误的.不需要异步代码在任何其他线程上运行.

That belief is common but false. There is no requirement that asynchronous code run on any second thread.

想象一下,您正在做早餐.您在烤面包机中放了一些烤面包,而在等待烤面包出炉的同时,您从昨天开始浏览邮件,支付一些账单,然后,突然出现了烤面包.您完成了帐单的支付,然后在烤面包上涂黄油.

Imagine that you are cooking breakfast. You put some toast in the toaster, and while you are waiting for the toast to pop, you go through your mail from yesterday, pay some bills, and hey, the toast popped up. You finish paying that bill and then go butter your toast.

您在哪里雇了第二个工人看烤面包机?

Where in there did you hire a second worker to watch your toaster?

您没有.线程是工人.异步工作流可以全部发生在一个线程上.异步工作流的重点是避免,如果可能的话,避免雇用更多的工人.

You didn't. Threads are workers. Asynchronous workflows can happen all on one thread. The point of the asynchronous workflow is to avoid hiring more workers if you can possibly avoid it.

如果我有一个长时间运行的任务,该任务受CPU限制(比如说它在做大量困难的数学运算),那么异步运行该任务必须阻塞某些线程,对吗?确实需要做一些数学运算.

If I have a long running task that is CPU bound (let's say it is doing a lot of hard math), then running that task asynchronously must be blocking some thread right? Something has to actually do the math.

在这里,我给您解决一个难题.这是一列由100个数字组成的列;请手动将它们加起来.因此,您将第一个添加到第二个并进行总计.然后,将运行总计添加到第三个并获得总计.然后,哦,地狱,第二页的数字丢失了.记住你在哪里,然后去敬酒.哦,在敬酒的同时,还有剩余的数字都来了.给吐司涂黄油后,继续将这些数字相加,并记住下次有空的时候就吃吐司.

Here, I'll give you a hard problem to solve. Here's a column of 100 numbers; please add them up by hand. So you add the first to the second and make a total. Then you add the running total to the third and get a total. Then, oh, hell, the second page of numbers is missing. Remember where you were, and go make some toast. Oh, while the toast was toasting, a letter arrived with the remaining numbers. When you're done buttering the toast, go keep on adding up those numbers, and remember to eat the toast the next time you have a free moment.

您在哪里雇用了另一名工人来添加数字? 计算上昂贵的工作不必同步,也不需要阻塞线程.使计算工作可能异步的原因是能够停止计算,记住您在哪里,去做其他事情,记住在那之后做什么 以及在您离开的地方继续工作的能力.

Where is the part where you hired another worker to add the numbers? Computationally expensive work need not be synchronous, and need not block a thread. The thing that makes computational work potentially asynchronous is the ability to stop it, remember where you were, go do something else, remember what to do after that, and resume where you left off.

现在,雇用第二名工人肯定是可能,他除了加数字外什么也不做,然后被解雇.你可以问那个工人你做完了吗?"如果答案是否定的,您可以做一个三明治直到完成.这样您和工人都很忙.但是没有要求,异步涉及多个工作人员.

Now it is certainly possible to hire a second worker who does nothing but add numbers, and then is fired. And you could ask that worker "are you done?" and if the answer is no, you could go make a sandwich until they are done. That way both you and the worker are busy. But there is not a requirement that asynchrony involve multiple workers.

如果我等待它,那么某些线程将被阻塞.

If I await it then some thread is getting blocked.

不,不,不.这是您误会中最重要的部分. await并不意味着异步开始执行此作业". await的意思是我在这里有一个异步产生的结果,可能不可用.如果不可用,请找到在此线程上要做的其他工作,这样我们就不会阻塞线程.等待与您刚才说的相反.

NO NO NO. This is the most important part of your misunderstanding. await does not mean "go start this job asynchronously". await means "I have an asynchronously produced result here that might not be available. If it is not available, find some other work to do on this thread so that we are not blocking the thread. Await is the opposite of what you just said.

什么是真正异步方法的示例,它们如何实际工作?是否仅限于那些利用某些硬件功能的I/O操作,从而不会阻塞任何线程?

What is an example of a truly asynchronous method and how would they actually work? Are those limited to I/O operations which take advantage of some hardware capabilities so no thread is ever blocked?

异步工作通常涉及自定义硬件或多个线程,但不是必需的.

Asynchronous work often involves custom hardware or multiple threads, but it need not.

不要考虑工人.考虑工作流程.异步的本质是将工作流分解成小部分,这样您可以确定这些部分必须发生的顺序,然后依次执行每个部分,但是允许相互不依赖的部分进行交错.

Don't think about workers. Think about workflows. The essence of asynchrony is breaking up workflows into little parts such that you can determine the order in which those parts must happen, and then executing each part in turn, but allowing parts that do not have dependencies with each other to be interleaved.

在异步工作流程中,您可以轻松地检测到工作流程中表示零件之间相关性的位置.这些部分用await标记.这就是await的含义:后面的代码取决于工作流的这一部分是否已完成,因此,如果未完成,请查找其他要做的任务,然后在任务完成后返回此处.整个问题的关键是即使在未来会产生所需结果的世界中,也要保持工人的工作.

In an asynchronous workflow you can easily detect places in the workflow where a dependency between parts is expressed. Such parts are marked with await. That's the meaning of await: the code which follows depends upon this portion of the workflow being completed, so if it is not completed, go find some other task to do, and come back here later when the task is completed. The whole point is to keep the worker working, even in a world where needed results are being produced in the future.

这篇关于关于线程以及异步方法在C#中是否真正异步的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆