我是线程和异步编程的新手。我正在努力学习这些概念,到目前为止,我理解了这些概念,但我有一个问题要问。
假设我想调用一个名为GetAllUsers()的方法,该方法需要很长时间才能执行,在某种程度上它不会阻塞资源并保持UI响应。所以,我所理解的是,它可以用三种方法来完成(请让我知道这些方法是否正确,或者我完全错了):
1)线程:我可以生成一个新的线程,并将GetAllUsers方法作为线程开始。这将在另一个线程上开始执行该方法,使我的ui保持响应,当调用完成时,我可以使用路由技术来更新UI控件,即InvokeRequired。我的理解正确吗?
或
2)异步委托:可以创建委托。创建它的一个新实例,并将其指向方法GetAllUsers。然后使用BeginInvoke方法。幕后的BeginInvoke将产生一个新的线程,并运行我的方法,使UI保持响应。当调用完成时,将调用回调方法,并再次使用路由技术来更新GUI线程上的控件。我的理解正确吗?
或
3) Async/ await :将外部方法标记为async,并将方法GetAllUsers的调用标记为await。这也将使UI保持响应,因为运行它的线程可以跳出来做一些其他工作,直到对这个缓慢方法的调用完成。我的理解正确吗?
现在,问题是-如果你读了下面链接上的第二段,它说async/await不会导致创建额外的线程。那么async/await如何在不创建任何额外线程的情况下提供与上面的第一个2解决方案相同的输出呢?解决方案1和2将导致多线程,但异步解决方案不会。异步/等待是如何在幕后工作的?
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads
发布于 2013-10-29 08:18:35
我的理解正确吗?
是的,你的理解是正确的。
现在,问题是-如果你读了下面链接上的第二段,它说
/await不会导致创建额外的线程。那么async/await如何在不创建任何额外线程的情况下提供与上面的第一个2解决方案相同的输出呢
async
修饰符和await
操作符不一定要创建新线程。执行异步的实际机制由调用await
的类型处理。如果您使用await Task.Run(() => YourMethod());
,那么Task.Run
将使用线程池线程来执行操作。
但是,如果您可以修改您的方法,使GetAllUsers
使用异步IO调用而不是线程,那么await
将不需要使用线程来实现异步。例如,如果GetAllUsers
的大部分时间都在等待服务器上的下载,那么使用异步web将允许您在不使用额外线程的情况下使该方法异步。
在这种情况下,即使您必须将Task.Run
与await
一起使用,这里也有一个很好的优势--您可以修改您的方法以使用await
,而不会弄乱其逻辑控制流,保持异常处理的整洁,并且不必担心使用BeginInvoke
将其推回到UI线程-使用await
,所有这些“混乱”都会为您处理,并且您的代码可以非常接近原始的非异步代码。
https://stackoverflow.com/questions/19647369
复制相似问题