关于确保在 IAsyncResult 对象列表上调用 EndInvoke() 的两个问题

发布于 2024-09-05 18:10:13 字数 1105 浏览 2 评论 0原文

因此,这个问题是关于 .Net IAsyncResult 设计模式以及调用 EndInvoke 的必要性,如 这个问题

背景

我有一些代码,我正在对特定函数发起潜在的许多异步调用,然后等待在使用 EndInvoke() 返回所有结果之前完成所有这些调用。

问题 1

在调用 EndInvoke() 之前,我不知道是否有任何调用遇到异常,如果其中一个调用发生异常,整个方法应该失败,并且异常会被包装到 API 特定异常中并向上抛出。

所以我的第一个问题是确保其余异步调用正确终止的最佳方法是什么?

在未终止的调用的其余部分上调用 EndInvoke()(并忽略任何进一步的异常)的 finally 块是执行此操作的最佳方法吗?

问题 2

其次,当我第一次触发所有异步调用时,我会在我的 WaitHandle 实例数组上调用 WaitHandle.WaitAll()从我的 IAsyncResult 实例中获取。触发所有这些异步调用的方法需要遵守超时,因此我将其提供给 WaitAll() 方法。然后我测试所有调用是否已完成,如果没有完成,则必须已达到超时,因此该方法也应该失败并抛出另一个特定于 API 的异常。

所以我的第二个问题是在这种情况下我应该做什么?

我需要在抛出错误之前调用 EndInvoke() 来终止所有这些异步调用,但同时我不希望代码因 EndInvoke() 而陷入困境> 正在阻塞。理论上,至少如果 WaitAll() 调用超时,那么所有异步调用本身都应该超时并抛出异常(从而完成调用),因为它们也受超时控制,但此超时是可能与主超时不同

So this question is regarding the .Net IAsyncResult design pattern and the necessity of calling EndInvoke as covered in this question

Background

I have some code where I'm firing off potentially many asynchronous calls to a particular function and then waiting for all these calls to finish before using EndInvoke() to get back all the results.

Question 1

I don't know whether any of the calls has encountered an exception until I call EndInvoke() and in the event that an exception occurs in one of the calls the entire method should fail and the exception gets wrapped into an API specific exception and thrown upwards.

So my first question is what's the best way then to ensure that the remainder of the async calls get properly terminated?

Is a finally block which calls EndInvoke() on the remainder of the unterminated calls (and ignores any further exceptions) the best way to do this?

Question 2

Secondly when I first fire off all my asyc calls I then call WaitHandle.WaitAll() on the array of WaitHandle instances that I've got from my IAsyncResult instances. The method which is firing all these async calls has a timeout to adhere to so I provide this to the WaitAll() method. Then I test whether all the calls have completed, if not then the timeout must have been reached so the method should also fail and throw another API specific exception.

So my second question is what should I do in this case?

I need to call EndInvoke() to terminate all these async calls before I throw the error but at the same time I don't want the code to get stuck since EndInvoke() is blocking. In theory at least if the WaitAll() call times out then all the async calls should themselves have timed out and thrown exceptions (thus completing the call) since they are also governed by a timeout but this timeout is potentially different from the main timeout

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

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

发布评论

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

评论(2

蓬勃野心 2024-09-12 18:10:13

我将迭代您的 IAsyncResult 对象,将每个 EndInvoke 包装在 try/catch 中,将任何生成的异常存储在其他地方。然后,当您调用所有 EndInvoke 时,您可以查看是否存储了任何异常,如果是,则抛出 API 异常。像这样的东西:

var exs = new List<Exception>();

foreach (IAsyncResult iasr in asyncResults) {
    try {
        iasr.EndInvoke();
    }
    catch (Exception e) {
        exs.Add(e);
    }
}

if (exs.Count > 0) {
    throw new MyException(exs.ToReadOnly());
}

I would iterate through your IAsyncResult objects, wrapping each EndInvoke in a try/catch that stores any generated exception somewhere else. Then, when you've called all the EndInvokes, you can see if you've stored any exceptions and throw an API exception if so. Something like:

var exs = new List<Exception>();

foreach (IAsyncResult iasr in asyncResults) {
    try {
        iasr.EndInvoke();
    }
    catch (Exception e) {
        exs.Add(e);
    }
}

if (exs.Count > 0) {
    throw new MyException(exs.ToReadOnly());
}
饮湿 2024-09-12 18:10:13

如果可能的话,我建议使用任务而不是 IAsyncResult。它们具有更好的“延续”语义,并且可以包装 IAsyncResult API,为您适当地调用 EndInvoke。

I recommend using Tasks instead of IAsyncResult if at all possible. They have nicer "continuation" semantics, and can wrap an IAsyncResult API, calling EndInvoke appropriately for you.

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