如何取消异步调用? [英] How to cancel an asynchronous call?
问题描述
如何取消异步调用?在.NET APM似乎并不支持此操作。
How to cancel an asynchronous call? The .NET APM doesn't seem to support this operation.
我有以下的环在我的code的派生多个线程的线程池。当我点击我的用户界面的一个按钮,我想这些线程(或异步调用)结束。
I have the following loop in my code which spawns multiple threads on the ThreadPool. When I click a button on my UI, I would like these threads (or asynchronous calls) to end.
foreach (var sku in skus)
{
loadSku.BeginInvoke(...
}
有没有优雅的解决方案不是创建一个全球性的取消标记,并具有异步方法来寻找它的其他?
Is there any elegant solution other than creating a global "Cancel flag" and having the asynchronous methods to look for it?
推荐答案
取消标记,就是要做到这一点,虽然不是全球性的,不一定。不可避免的一点是,你需要的一些的方式发信号给线程,它应该停止它在做什么。
A "cancel flag" is the way to do it, though not a global one, necessarily. The unavoidable point is that you need some way to signal to the thread that it should stop what it's doing.
在的BeginInvoke
的情况下,这是很难做什么,但一个全球性的标志,因为工作开展的线程池,而你不知道哪个线程。你有几个选项(在顺序preference):
In the case of BeginInvoke
, this is hard to do with anything but a global flag, because the work is carried out on the threadpool, and you don't know which thread. You have a couple of options (in order of preference):
- 使用
的BackgroundWorker
,而不是的BeginInvoke
的。这有<一个href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx">cancellation功能烤入。这有其他好处,如<一href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx">progress监测和<一href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx">"Work完整的回调,也很好处理异常的。 - 使用
ThreadPool.QueueUserWorkItem
,传递一个对象具有状态的取消()
方法,设置一个取消
标志,正在执行的code可以检查。当然,你需要保持一个参考状态对象,所以你可以调用取消()
就可以了(这是后话了的BackgroundWorker
为你做 - 你有一个组件的形式(感谢弗雷德里克提醒一下。这一点)。 - 创建你自己的
的ThreadStart
委托,传递一个状态对象与选项2。
- Use the
BackgroundWorker
instead ofBeginInvoke
. This has cancellation functionality baked-in. This has other benefits, like progress monitoring, and "Work complete" callbacks. It also nicely handles exceptions. - Use
ThreadPool.QueueUserWorkItem
, passing in an object as the state that has aCancel()
method that sets aCancelled
flag that the executing code can check. Of course you'll need to keep a reference to the state object so you can callCancel()
on it (which is something theBackgroundWorker
does for you - you have a component on your form. (Thanks to Fredrik for reminding about this). - Create your own
ThreadStart
delegate, passing in a state object as with option 2.
这篇关于如何取消异步调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!