如果异步委托调用永远不会返回会发生什么?

发布于 2024-09-04 23:06:39 字数 523 浏览 1 评论 0原文

我找到了一个看起来不错的示例,说明如何在超时情况下异步调用委托... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c。 .aspx.总之,它使用带有超时的 WaitOne 来确定调用是否在超时到期之前未返回。

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

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

I found a decent looking example of how to call a delegate asynchronously with a timeout... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx. In summary it uses WaitOne with a timeout to determine if the call does not return before the timeout expires.

I also know that you should have an EndInvoke to match each BeginInvoke.

So what happens if the wait timeout expires? We (presumably) DON'T want to call EndInvoke as that will block. The code can go on to do 'other things', but have we leaked anything? Is there some poor thread someplace blocked waiting for a return that's never going to happen? Have we leaked some memory where the result-that-will-never-return was going to be placed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

双手揣兜 2024-09-11 23:06:39

我认为这个帖子谈得很好:

来自帖子:

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

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

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

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

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

I think this post talks about it very well:

From the post:

You can't terminate an executing async delegate if it's not your thread, but you can if it is. If you use the common BeginInvoke type methods, you get a thread pool thread managed by the framework. If you use the Thread() class you get you own thread to manage, start, suspend, etc. as you like.

Developing asychronously requires that one decide who will manage the threads. The many different methods that execute asynchronously are using the ThreadPool threads behind the scenes.

Since you can't/shouldn't terminate a thread pool thread then you must design you code to communicate with the thread so that it can exit. The MSDN examples for the BackgroundWorker component demonstrates this kind of communication.

Sometimes your code may have the thread blocking waiting for IO. Here you would normally use a multiple object wait instead, waiting for IO or for a ManualResetEvent.

So in short, youll need to find a way to manage the threads yourself if there is a possibility of timing out and you want the thread to end.

活泼老夫 2024-09-11 23:06:39

您需要调用 EndInvoke()。

这是一个讨论 EndInvoke() 发生的情况的链接:

EndInvoke() 是可选的,有点可选,还是绝对不是可选的?

这是一个 链接到已接受答案中的文章。

我们一直在各种公共论坛上讨论异步委托调用的“即发即忘”技术。许多 DevelopMentor 讲师都撰写了展示该技术的文章和示例代码,我们都在课堂上进行了描述。当然,当时唐的书中也有这样的内容。因此,当微软最终记得让外界知道这种技术实际上并不合法时,这是相当令人惊讶的。

有关异步模式的 MSDN 链接

You need to call EndInvoke().

Here is a link talking about what happens with EndInvoke():

Is EndInvoke() optional, sort-of optional, or definitely not optional?

Here is a link to the article in the accepted answer.

We had all been talking about the 'fire and forget' technique with asynchronous delegate invocation in various public forums. Many DevelopMentor instructors had written articles and example code showing the technique, and we had all described it in class. And of course it was in Don's book by then too. So when Microsoft eventually remembered to let the outside world know that this technique is not in fact legal, it was rather astonishing.

An MSDN link on the asynchronous pattern.

上课铃就是安魂曲 2024-09-11 23:06:39

您将泄漏线程持有的资源。将会有各种 .NET 远程处理对象,例如 AsyncResult。与线程关联的几个非托管句柄。与您将泄漏的由线程堆栈持有的一兆字节虚拟内存地址空间相比,这一切都微不足道。

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

You will leak the resources held by the thread. There will be various bits of .NET remoting plumbing objects like the AsyncResult. Several unmanaged handles associated with the thread. All peanuts compared to the one megabyte of virtual memory address space you'll leak, held by the thread stack.

You cannot abort the thread in any way, the leak is permanent. When you have to deal with badly behaving code like this, your only good resource is to run it in a separate process so you can get Windows to clean up the shrapnel when you shoot the process in the head with Process.Kill(). Even that is not guaranteed, these kind of freezes tend to be associated with misbehaving device drivers. Process.Kill won't terminate a device driver thread. Easy to see: trying to abort the process with Taskmgr.exe will leave it running with one Handle. You have some hope if that doesn't happen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文