C# 如果异步委托调用从未返回,会发生什么?

C# 如果异步委托调用从未返回,会发生什么?,c#,.net,asynchronous,timeout,delegates,C#,.net,Asynchronous,Timeout,Delegates,我发现了一个不错的例子,说明了如何在超时的情况下异步调用委托。总之,它使用带超时的WaitOne来确定调用是否在超时过期之前返回 我还知道您应该有一个EndInvoke来匹配每个BeginInvoke 那么,如果等待超时过期会发生什么呢?我们(大概)不想调用EndInvoke,因为这样会阻塞。代码可以继续做“其他事情”,但我们是否泄露了任何信息?是否有一些可怜的线程在某个地方被阻塞,等待永远不会发生的返回?我们是否泄漏了一些内存,这些内存将永远不会返回结果?您需要调用EndInvoke() 下面

我发现了一个不错的例子,说明了如何在超时的情况下异步调用委托。总之,它使用带超时的WaitOne来确定调用是否在超时过期之前返回

我还知道您应该有一个EndInvoke来匹配每个BeginInvoke

那么,如果等待超时过期会发生什么呢?我们(大概)不想调用EndInvoke,因为这样会阻塞。代码可以继续做“其他事情”,但我们是否泄露了任何信息?是否有一些可怜的线程在某个地方被阻塞,等待永远不会发生的返回?我们是否泄漏了一些内存,这些内存将永远不会返回结果?

您需要调用EndInvoke()

下面是一个链接,讨论EndInvoke()的情况:

以下是对已接受答案中文章的一个补充

在各种公共论坛上,我们都在讨论异步委托调用的“fire-and-forget”技术。许多开发指导人员都写过文章和示例代码来展示这项技术,我们都在课堂上对其进行了描述。当然,那时候它也在唐的书中。因此,当微软最终记得让外界知道这项技术事实上并不合法时,这是相当令人震惊的

一个关于异步模式的MSDN。

我认为post对此进行了很好的讨论:

从职位:

如果一个正在执行的异步委托不是你的线程,你不能终止它,但是如果它是你的线程,你可以终止它。如果使用常见的BeginInvoke类型方法,则会得到一个由框架管理的线程池线程。如果您使用Thread()类,您将获得自己的线程来管理、启动、挂起等

非同步开发需要决定谁来管理线程。异步执行的许多不同方法都在幕后使用线程池线程

既然您不能/不应该终止线程池线程,那么您必须设计与线程通信的代码,以便它可以退出。BackgroundWorker组件的MSDN示例演示了这种通信

有时您的代码可能会有线程阻塞等待IO。在这里,您通常使用多对象等待,等待IO或ManualResetEvent


因此,简言之,如果有可能超时,并且希望线程结束,您需要找到一种方法自己管理线程。

您将泄漏线程所拥有的资源。将有各种各样的.NET远程处理管道对象,如AsyncResult。与线程关联的多个非托管句柄。与线程堆栈将泄漏的1兆字节虚拟内存地址空间相比,所有这些都是微不足道的

您不能以任何方式中止线程,泄漏是永久性的。当您必须处理这样的行为不好的代码时,您唯一的好办法就是在单独的进程中运行它,这样当您使用process.Kill()向进程头部射击时,您可以让Windows清理碎片。即使不能保证这一点,这些类型的冻结往往与行为不端的设备驱动程序有关。Kill不会终止设备驱动程序线程。很容易看到:尝试使用Taskmgr.exe中止进程将使其只运行一个句柄。如果那不发生,你还有希望