Thread vs begininvoke vs async



我是线程和异步编程的新手。我正在尝试学习这些概念,到目前为止我理解它,但有一个问题要问。

假设我想调用一个名为 GetAllUsers() 的方法,该方法需要很长时间才能执行,在某种程度上它不会阻塞资源并保持 UI 响应。所以,我的理解是,它可以通过 3 种方式完成(请让我知道这些是否正确或我完全弄错了):-

1)线程:我可以生成一个新线程,并给出GetAllUsers方法作为线程启动。这将在不同的线程上开始执行该方法,保持我的 UI 响应,当调用完成后,我可以使用路由技术来更新 UI 控件,即 InvokeRequired。我的理解正确吗?

2)异步委托:我可以创建一个委托。创建它的新实例,并将其指向方法 GetAllUsers。然后使用 BeginInvoke 方法。引擎盖下的 BeginInvoke 将生成一个新线程并运行我的方法,保持 UI 响应。调用完成后,将调用回调方法,并再次使用路由技术来更新 GUI 线程上的控件。我的理解正确吗?

3) 异步/等待:将外部方法标记为异步,并将对方法 GetAllUsers 的调用标记为等待。这也将使 UI 保持响应,因为运行它的线程可以跳出并执行一些其他工作,直到对此慢速方法的调用完成。我的理解正确吗?

现在,问题是 - 如果您阅读下面链接上的第 2 段,它说 async/await 不会导致创建额外的线程。那么 async/await 如何在不创建任何其他线程的情况下设法提供与上述第一个 2solution 相同的输出。解决方案 1 和 2 将导致多线程,但异步解决方案不会。异步/等待如何在引擎盖下工作。?

http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads

我的理解正确吗?

是的,你的理解是正确的。

现在,问题是 - 如果您阅读下面链接上的第 2 段,它说 async/await 不会导致创建额外的线程。那么 async/await 如何在不创建任何其他线程的情况下设法提供与上面第一个 2solution 相同的输出

async修饰符和await运算符不一定会创建新线程。 执行异步的实际机制由调用 await 的类型处理。 如果使用 await Task.Run(() => YourMethod()); ,则Task.Run确实使用线程池线程来执行该操作。

但是,如果可以重新设计方法,以便GetAllUsers使用异步 IO 调用而不是线程,则await不需要使用线程来异步。 例如,如果GetAllUsers大部分时间都在等待从服务器下载,则使用异步 Web API 将允许你在不使用额外线程的情况下使该方法异步。

在这种情况下,即使你必须将Task.Runawait一起使用,这里也有一个很好的优势 - 你可以重新设计你的方法以使用await,而不会弄乱它的逻辑控制流,保持异常处理干净,而不必担心使用BeginInvoke推回UI线程 - 使用await, 所有这些"混乱"都是为您处理的,并且您的代码可以非常接近原始的非异步代码。

最新更新