我找到了一个体面的示例,说明如何使用超时... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx异步调用委托。总而言之,它使用具有超时的WaitOne来确定在超时到期之前调用是否未返回。
我也知道你应该有一个EndInvoke来匹配每个BeginInvoke。
那么等待超时到期会发生什么?我们(大概)不想调用EndInvoke,因为它会阻止。代码可以继续做“其他事情”,但我们泄露了什么?是否有一些可怜的线程在某个地方被阻止等待返回永远不会发生的事情?我们是否泄露了一些记忆,其结果是永远不会返回?
答案 0 :(得分:5)
我认为this帖子谈得很清楚:
来自帖子:
如果不是你的线程,你不能终止执行的异步委托,但如果是的话,你就可以。如果使用常见的BeginInvoke类型方法,则会获得由框架管理的线程池线程。如果您使用Thread()类,您可以根据需要获得自己的线程来管理,启动,暂停等。
异步开发需要决定谁来管理线程。异步执行的许多不同方法都是在幕后使用ThreadPool线程。
由于您不能/不应该终止线程池线程,因此您必须设计代码以与线程通信以便它可以退出。 BackgroundWorker组件的MSDN示例演示了这种通信。
有时您的代码可能会阻塞等待IO的线程。在这里,您通常会使用多个对象等待,等待IO或手动重置事件。
简而言之,如果有可能超时并希望线程结束,你需要找到一种自己管理线程的方法。
答案 1 :(得分:4)
您需要调用EndInvoke()。
这是一个关于EndInvoke()会发生什么的链接:
Is EndInvoke() optional, sort-of optional, or definitely not optional?
以下是接受答案中文章的link。
在各种公共论坛中,我们一直在讨论“发射并忘记”技术和异步委托调用。许多DevelopMentor教师都写了文章和示例代码来展示这种技术,我们在课堂上对它进行了描述。当然,那时也是唐的书。因此,当微软最终记得让外界知道这种技术实际上并不合法时,这是相当令人惊讶的。
异步模式上的MSDN link。
答案 2 :(得分:3)
您将泄漏线程持有的资源。会有各种各样的.NET远程管道对象,如AsyncResult。与线程关联的几个非托管句柄。所有花生都与线程堆栈保存的1兆字节虚拟内存地址空间相比较。
你不能以任何方式中止线程,泄漏是永久性的。当你必须处理这样的行为不当的代码时,你唯一的好资源是在一个单独的进程中运行它,这样你就可以在使用Process.Kill()在头部开始进程时让Windows清理弹片。即使这不能保证,这种冻结往往与行为不端的设备驱动程序有关。 Process.Kill不会终止设备驱动程序线程。很容易看到:尝试使用Taskmgr.exe中止该过程将使其与一个Handle一起运行。如果没有发生,你会有一些希望。