什么是异步编程和多线程的区别? [英] What is the difference between asynchronous programming and multithreading?

查看:129
本文介绍了什么是异步编程和多线程的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为他们基本上是相同的事 - 编写处理器之间分配任务的程序(对具有2 +处理器的计算机)。然后我读 https://msdn.microsoft.com/en-us/库/ hh191443.aspx ,该说

I thought that they were basically the same thing -- writing programs that split tasks between processors (on machines that have 2+ processors). Then I'm reading https://msdn.microsoft.com/en-us/library/hh191443.aspx, which says

异步方法旨在被非阻塞操作。一个的await
  前pression在异步方法不会阻止当前线程,而
  等候的任务正在运行。相反,前pression迹象了休息
  该方法的延续和收益的控制权的调用者
  异步方法。

Async methods are intended to be non-blocking operations. An await expression in an async method doesn’t block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.

异步和等待关键字不会造成额外的线程是
  创建。异步方法不需要多线程因为异步
  方法并不在自己的线程中运行。该方法对当前运行
  同步上下文和使用时间的线程上,只有当
  方法是有效的。您可以使用Task.Run移动CPU绑定的工作提高到一个
  后台线程,而是后台线程不以过程中提供帮助
  这只是等待结果变得可用。

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

和我想知道是否有人能翻译的英语我。这似乎借鉴asyncronicity之间的区别(就是一个字?)和线程,并暗示你可以有一个具有异步任务,但没有多线程的程序。

and I'm wondering whether someone can translate that to English for me. It seems to draw a distinction between asyncronicity (is that a word?) and threading and imply that you can have a program that has asynchronous tasks but no multithreading.

现在我明白了异步任务的想法,如对皮克的例子。的全碟的 C#的深入,第三版

Now I understand the idea of asynchronous tasks such as the example on pg. 467 of Jon Skeet's C# In Depth, Third Edition

async void DisplayWebsiteLength ( object sender, EventArgs e )
{
    label.Text = "Fetching ...";
    using ( HttpClient client = new HttpClient() )
    {
        Task<string> task = client.GetStringAsync("http://csharpindepth.com");
        string text = await task;
        label.Text = text.Length.ToString();
    }
}

异步关键字工具的此功能,当它被调用时,不会在其其调用之后需要的一切建成一个上下文调用被称为

在换言之,在某些任务的中间写它

In other words, writing it in the middle of some task

int x = 5; 
DisplayWebsiteLength();
double y = Math.Pow((double)x,2000.0);

,因为 DisplayWebsiteLength()无关与 X ,会引起 DisplayWebsiteLength()在后台被执行,像

, since DisplayWebsiteLength() has nothing to do with x or y, will cause DisplayWebsiteLength() to be executed "in the background", like

                processor 1                |      processor 2
-------------------------------------------------------------------
int x = 5;                                 |  DisplayWebsiteLength()
double y = Math.Pow((double)x,2000.0);     |

显然,这是一个愚蠢的例子,但我是正确的还是我完全糊涂了还是什么?

Obviously that's a stupid example, but am I correct or am I totally confused or what?

(另外,我很困惑,为什么发件人电子通常不会在体内使用上述功能。)

(Also, I'm confused about why sender and e aren't ever used in the body of the above function.)

推荐答案

您误解非常普遍。很多人都在告诉我们,多线程和异步都是一样的东西,但事实并非如此。

Your misunderstanding is extremely common. Many people are taught that multithreading and asynchrony are the same thing, but they are not.

这是比喻通常有助于。你做饭的餐厅。一个订单进来鸡蛋和烤面包。

An analogy usually helps. You are cooking in a restaurant. An order comes in for eggs and toast.


  • 同步:你煮鸡蛋,那么你煮烤面包

  • 异步,单线程:你开始把鸡蛋烹饪和设置一个计时器。你开始敬酒做饭,并设置一个计时器。虽然他们都是做饭,清洁厨房。当计时器熄灭你脱下热鸡蛋和烤面包了烤面包机,并为他们提供服务。

  • 异步的,多线程:你雇用两名厨师,一个煮鸡蛋,一到做饭敬酒。现在你有协调的厨师,让他们不与对方在厨房共享资源时发生冲突的问题。而且你必须向他们支付。

现在是否有意义的多线程只是一种不同步? 线程大约是工人;异步约为任务。在多线程的工作流程,你将任务分配给工人。在异步单线程工作流程您拥有的一些任务依赖于他人成果的任务的图。每个任务完成它调用code,它给出的时间表刚刚完成的任务的结果下一个任务,可以运行。但是,你(希望)只需要一个工人来执行所有任务,每个任务没有一个工人。

Now does it make sense that multithreading is only one kind of asynchrony? Threading is about workers; asynchrony is about tasks. In multithreaded workflows you assign tasks to workers. In asynchronous single-threaded workflows you have a graph of tasks where some tasks depend on the results of others; as each task completes it invokes the code that schedules the next task that can run, given the results of the just-completed task. But you (hopefully) only need one worker to perform all the tasks, not one worker per task.

这将有助于认识到,许多任务并不是处理器的约束。对于处理器密集型任务是有意义的雇佣尽可能多的工人(线程)因为有处理器,一个任务分配给每个工人,一个处理器分配给每个工人,并让每个处理器做没有别的工作,但计算结果作为尽快。但是对于那些没有在处理器上等待任务,你并不需要在所有指派一名工人。你只是等待消息到达的结果是提供的做其他的事情,而你正在等待的。当那么邮件到达您可以安排完成的任务,因为你的待办事项清单上的下一件事的延续来检查了。

It will help to realize that many tasks are not processor-bound. For processor-bound tasks it makes sense to hire as many workers (threads) as there are processors, assign one task to each worker, assign one processor to each worker, and have each processor do the job of nothing else but computing the result as quickly as possible. But for tasks that are not waiting on a processor, you don't need to assign a worker at all. You just wait for the message to arrive that the result is available and do something else while you're waiting. When that message arrives then you can schedule the continuation of the completed task as the next thing on your to-do list to check off.

因此​​,让我们来看看Jon的例子的更多细节。发生了什么?

So let's look at Jon's example in more detail. What happens?


  • 有人调用DisplayWebSiteLength。谁?我们不关心。

  • 它设置一个标签,创建一个客户,并要求客户去取东西。客户端返回一个对象重新presenting取东西的任务。这项任务正在进行中。

  • 它是在另一个线程的进展?可能不会。阅读关于为什么没有线程的链接斯蒂芬的文章。

  • 现在,我们等待的任务。发生了什么?我们检查该任务是否我们创造它,我们期待它的时间之间完成。如果是的话,那么我们获取的结果,并继续运行。让我们假设它尚未完成。 我们的这种方法的剩余部分注册成为该任务的延续,返回

  • 现在,已经控制返回给调用者。它有什么作用?不管就是了。

  • 现在,假设任务完成。它是如何做到的?也许它是在另一个线程,或者来电,我们只是回到了允许它在当前线程上运行完成运行。无论如何,我们现在有一个完成的任务。

  • 将完成的任务要求正确的线程 - 再次,可能是的只有的线程 - 运行任务的延续。

  • 控制传递马上回到我们只是留在的await的点的方法。现在有可用的结果,所以我们可以指定文本和运行方法的其余部分。

  • Someone invokes DisplayWebSiteLength. Who? We don't care.
  • It sets a label, creates a client, and asks the client to fetch something. The client returns an object representing the task of fetching something. That task is in progress.
  • Is it in progress on another thread? Probably not. Read the link to Stephen's article on why there is no thread.
  • Now we await the task. What happens? We check to see if the task has completed between the time we created it and we awaited it. If yes, then we fetch the result and keep running. Let's suppose it has not completed. We sign up the remainder of this method as the continuation of that task and return.
  • Now control has returned to the caller. What does it do? Whatever it wants.
  • Now suppose the task completes. How did it do that? Maybe it was running on another thread, or maybe the caller that we just returned to allowed it to run to completion on the current thread. Regardless, we now have a completed task.
  • The completed task asks the correct thread -- again, likely the only thread -- to run the continuation of the task.
  • Control passes immediately back into the method we just left at the point of the await. Now there is a result available so we can assign text and run the rest of the method.

这就像在我的比喻。有人问你为一个文件。您在邮件送走的文档,并继续做其他工作。当它在邮件到达你发出信号,当你感觉它,你做的工作流程的其余部分 - 打开信封,付提货费,等等。你并不需要聘请另一名工人做一切你。

It's just like in my analogy. Someone asks you for a document. You send away in the mail for the document, and keep on doing other work. When it arrives in the mail you are signalled, and when you feel like it, you do the rest of the workflow -- open the envelope, pay the delivery fees, whatever. You don't need to hire another worker to do all that for you.

这篇关于什么是异步编程和多线程的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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