简体   繁体   English

线程,任务,异步/等待,线程池

[英]Threads, Task, async/await, Threadpool

I am getting really confused here about multithreading :( I am reading about the C# Async/Await keywords. I often read, that by using this async feature, the code gets executed "non-blocking". People put code examples in two categories "IO-Bound" and "CPU-bound" - and that I should not use a thread when I execute io-bound things, because that thread will just wait .. 我在这里对多线程感到非常困惑:(我正在阅读关于C#Async / Await关键字。我经常读到,通过使用这个异步功能,代码被执行“非阻塞”。人们将代码示例分为两类“ IO-Bound“和”CPU绑定“ - 我执行io-bound时我不应该使用线程,因为该线程只会等待..

I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ? 我不明白......如果我不想让用户等待操作,我必须在另一个线程上执行该操作,对吧?

If I use the Threadpool, an instance of "Thread"-class, delegate.BeginInvoke or the TPL -- every asynchronous execution is done on another thread. 如果我使用Threadpool,一个“Thread”-class,delegate.BeginInvoke或TPL的实例 - 每个异步执行都在另一个线程上完成。 (with or without a callback) (有或没有回调)

What you are missing is that not every asynchronous operation is done on another thread. 您缺少的是并非每个异步操作都在另一个线程上完成。 Waiting on an IO operation or a web service call does not require the creation of a thread. 等待IO操作或Web服务调用不需要创建线程。 On Windows this is done by using the OS I/O Completion Ports . 在Windows上,这是通过使用OS I / O完成端口完成的

What happens when you call something like Stream.ReadAsync is that the OS will issue a read command to the disk and then return to the caller. 当你调用Stream.ReadAsync东西时,操作系统会向磁盘发出一个读命令,然后返回给调用者。 Once the disk completes the read the notifies the OS kernel which will then trigger a call back to your processes. 磁盘完成读取后,会通知操作系统内核,然后操作系统将触发回调进程。 So there is no need to create a new threadpool thread that will just sit and block. 所以没有必要创建一个新的线程池线程,它只会坐下来阻塞。

What is meant is this: 这是什么意思:

Suppose you query some data from a database (on another server) - you will send a request and just wait for the answer. 假设您从数据库(在另一台服务器上)查询某些数据 - 您将发送请求并等待答案。 Instead of having a thread block and wait for the return it's better to register an callback that get's called when the data comes back - this is (more or less) what async/await does. 而不是有一个线程阻塞并等待返回,最好注册一个在数据返回时调用的回调 - 这是(或多或少)async / await的作用。 It will free the thread to do other things (give it back to the pool) but once your data come back asynchronously it will get another thread and continue your code at the point you left (it's really some kind of state-machine that handles that). 它将释放线程做其他事情(将其返回到池中)但是一旦您的数据异步返回它将获得另一个线程并在您离开位置继续您的代码(它实际上是某种处理该状态的状态机) )。

If your calculation is really CPU intensive (let's say you are calculating prime-numbers) things are different - you are not waiting for some external IO, you are doing heavy work on the CPU - here it's a better idea to use a thread so that your UI will not block. 如果你的计算真的是CPU密集型(让我们说你正在计算素数)事情是不同的 - 你不是在等待一些外部IO,你在CPU上做了很多工作 - 这里最好使用一个线程,这样你的用户界面不会阻止。

I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ? 我不明白......如果我不想让用户等待操作,我必须在另一个线程上执行该操作,对吧?

Not exactly. 不完全是。 An operation will take however long it is going to take. 不管怎样,手术都需要很长时间。 When you have a single-user application, running long-running things on a separate thread lets the user interface remain responsive. 当您拥有单用户应用程序时,在单独的线程上运行长时间运行的东西可以让用户界面保持响应。 At the very least this allows the UI to have something like a "Cancel" button that can take user input and cancel processing on the other thread. 至少这允许UI具有类似“取消”按钮的东西,其可以接受用户输入并取消对另一个线程的处理。 For some single-user applications, it makes sense to allow the user to keep doing other things while a long-running task completes (for example let them work on one file while another file is uploading or downloading). 对于某些单用户应用程序,允许用户在长时间运行的任务完成时继续执行其他操作(例如,让他们在另一个文件上载或下载时处理一个文件)是有意义的。

For web applications, you do not want to block a thread from the thread pool during lengthy(ish) IO, for example while reading from a database or calling another web service. 对于Web应用程序,您不希望在冗长(ish)IO期间阻塞线程池中的线程,例如在从数据库读取或调用其他Web服务时。 This is because there are only a limited number of threads available in the thread pool, and if they are all in use, the web server will not be able to accept additional HTTP requests. 这是因为线程池中只有有限数量的线程可用,如果它们全部在使用中,则Web服务器将无法接受其他HTTP请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM