代码之家  ›  专栏  ›  技术社区  ›  RobV

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

  •  0
  • RobV  · 技术社区  · 16 年前

    EndInvoke 包括在 this 问题

    背景

    我有一些代码,在这些代码中,我可能会对一个特定函数发出许多异步调用,然后等待所有这些调用在使用之前完成 EndInvoke() 为了得到所有的结果。

    问题1

    EndInvoke() 如果其中一个调用中发生异常,整个方法都会失败,异常会被包装成特定于API的异常并向上抛出。

    因此,我的第一个问题是,确保异步调用的其余部分正确终止的最佳方法是什么?

    finally 阻止哪个呼叫 对于剩余的未终止调用(并忽略任何其他异常),最好的方法是什么?

    问题2

    第二,当我第一次打掉所有的asyc电话时,我会打给你 WaitHandle.WaitAll() WaitHandle 我从我的 IAsyncResult 实例。触发所有这些异步调用的方法都有一个要遵守的超时,因此我将此提供给 WaitAll()

    所以我的第二个问题是在这种情况下我该怎么办?

    EndInvoke() EndInvoke() 正在阻塞。至少在理论上 调用超时-那么所有异步调用本身都应该超时并抛出异常(从而完成调用),因为它们也受超时控制,但此超时可能与主超时不同

    2 回复  |  直到 9 年前
        1
  •  1
  •   thecoop    16 年前

    我会反复浏览你的 IAsyncResult EndInvoke 结束调用 s、 您可以查看是否存储了任何异常,如果是,则抛出一个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());
    }
    
        2
  •  0
  •   Stephen Cleary    16 年前

    如果可能的话,我建议使用Tasks而不是IAsyncResult。它们有更好的“continuation”语义,可以包装一个IAsyncResult API,为您适当地调用EndInvoke。