UI线程有什么特别之处? [英] What's so special about UI thread?

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

问题描述

假设我有一个同步运行的方法fooCPU(它不会调用执行I/O的纯异步方法,也不会通过调用Task.Run或类似方式使用其他线程来运行其代码).该方法需要进行大量计算-受CPU限制.

Let's say I have a method fooCPU that runs synchronously (it doesn't call pure async methods performing I/O, or use other threads to run its code by calling Task.Run or similar ways). That method performs some heavy calculations - it's CPU bound.

现在,我在程序中调用fooCPU而不委托它由工作线程执行.如果fooCPU的一行需要很长时间才能运行,则直到完成为止,将不执行其他任何行.因此,例如,从UI线程调用它会导致UI线程冻结(GUI将变得无响应).

Now I call fooCPU in my program without delegating it to be executed by a worker thread. If one line of fooCPU will take long to run, no other lines will be executed until it finishes. So for example, calling it from the UI thread causes the UI thread to freeze (GUI will become unresponsive).

当我说 async/await是多线程的模仿时.两个不同代码段的代码行在单个线程上轮流执行.如果这些行之一需要很长时间才能运行,则直到完成为止,将不执行其他任何行.

When I stated that async/await is an imitation of mutlithreading. The lines of two different pieces of code are executed in turns, on a single thread. If one of these lines will take long to run, no other lines will be executed until it finishes.,

有人告诉我,UI线程上使用的异步是真的,但在所有其他情况下(ASP.NET,线程池上的异步,控制台应用程序等),情况并非如此.

I've been told that it's true for async used on the UI thread, but it's not true for all other cases (ASP.NET, async on the thread pool, console apps, etc).

谁能告诉我这可能意味着什么? UI线程与控制台程序的主线程有何不同?

Could anyone tell me what this might mean? How is UI thread different from the main thread of a console program?

我认为没有人希望这个论坛上的任何人继续讨论相关主题,例如它们出现在评论中,所以最好提出一个新问题.

I think nobody wants anyone here on this forum to continue the discussion of related topics, as they appear in the comments for instance, so it's better to ask a new question.

推荐答案

我建议您阅读我的 async介绍性帖子;它说明asyncawait关键字的工作方式.然后,如果您有兴趣编写异步代码,请继续我的 async最佳做法文章.

I recommend you read my async intro post; it explains how the async and await keywords work. Then, if you're interested in writing asynchronous code, continue with my async best practices article.

介绍性帖子的相关部分:

The relevant parts of the intro post:

与其他任何方法一样,执行异步方法的开头.也就是说,它会同步运行,直到遇到"await"(或引发异常)为止.

The beginning of an async method is executed just like any other method. That is, it runs synchronously until it hits an "await" (or throws an exception).

所以这就是为什么控制台代码示例中的内部方法的原因(没有await)正在同步运行.

So this is why the inner method in your console code example (without an await) was running synchronously.

Await检查该等待项是否已经完成;如果等待已完成,则该方法将继续运行(同步,就像常规方法一样).

Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running (synchronously, just like a regular method).

所以这就是为什么在控制台代码示例中外部方法的原因(这是await同步的内部方法)正在同步运行.

So this is why the outer method in your console code example (that was awaiting the inner method which was synchronous) was running synchronously.

稍后,当awaitable完成时,它将执行async方法的其余部分.如果您正在等待内置的等待(例如任务),那么异步方法的其余部分将在返回等待"之前捕获的上下文"上执行.

Later on, when the awaitable completes, it will execute the remainder of the async method. If you’re awaiting a built-in awaitable (such as a task), then the remainder of the async method will execute on a "context" that was captured before the "await" returned.

此上下文"为SynchronizationContext.Current,除非它为null,在这种情况下为TaskScheduler.Current.或者,更简单的版本:

This "context" is SynchronizationContext.Current unless it is null, in which case it is TaskScheduler.Current. Or, the simpler version:

上下文"到底是什么? 简单的答案:

What exactly is that "context"? Simple answer:

  1. 如果您使用的是UI线程,则它是一个UI上下文.
  2. 如果您要响应一个ASP.NET请求,那么它就是一个ASP.NET请求上下文.
  3. 否则,通常是线程池上下文.
  1. If you’re on a UI thread, then it’s a UI context.
  2. If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.
  3. Otherwise, it’s usually a thread pool context.

将所有这些放在一起,可以像这样工作地可视化async/await:该方法被拆分为多个块",每个await充当该方法被拆分的点.第一个块始终是同步运行的,并且在每个拆分点上,它可以同步或异步地继续.如果它异步地继续,那么它将在捕获的上下文中继续(默认情况下). UI线程提供了一个上下文,该上下文将在UI线程上执行下一个块.

Putting all of this together, you can visualize async/await as working like this: the method is split into several "chunks", with each await acting as a point where the method is split. The first chunk is always run synchronously, and at each split point it may continue either synchronously or asynchronously. If it continues asynchronously, then it will continue in a captured context (by default). UI threads provide a context that will execute the next chunk on the UI thread.

因此,要回答此问题,关于UI线程的特殊之处在于,它们提供了SynchronizationContext,该队列将工作排回到同一UI线程.

So, to answer this question, the special thing about UI threads is that they provide a SynchronizationContext that queues work back to that same UI thread.

我认为没有人希望这个论坛上的任何人继续讨论相关主题,例如它们出现在评论中,所以最好提出一个新问题.

I think nobody wants anyone here on this forum to continue the discussion of related topics, as they appear in the comments for instance, so it's better to ask a new question.

好吧,堆栈溢出专门旨在成为一个论坛;这是一个问题答案站点.因此,这里不是要求详尽的教程的地方.当您一劳永逸地尝试使代码正常工作时,或者如果您在研究了所有可能的知识后仍不了解某些内容时,这是一个好地方.这就是为什么(有目的地)限制对SO的注释的原因-它们必须简短,没有良好的代码格式等.此站点上的注释仅用于澄清目的,而不是作为讨论或论坛主题.

Well, Stack Overflow is specifically not intended to be a forum; it's a Question & Answer site. So it's not a place to ask for exhaustive tutorials; it's a place to come when you're stuck trying to get code working or if you don't understand something after having researched everything you can about it. This is why the comments on SO are (purposefully) restricted - they have to be short, no nice code formatting, etc. Comments on this site are intended for clarification, not as a discussion or forum thread.

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

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