0

“session.identify”是我调用但无权访问的第三方 COM API。它执行一个服务器查询,不知何故,偶尔会锁定(并因此停止等待结果的主程序)。

我的尝试是将它包装在 AsyncDelegate 中,这样我就可以给它一个超时,并且在超时到期后允许主程序继续进行(类似于这个,只有一个返回值)。但是,它仍然会锁定而超时没有效果。

我是否错误地使用了 AsyncHandle.WaitOne?API 中有什么东西可以阻止它被中止吗?

private delegate void AsyncIdentifyCaller(CoAudioIdSignature signature, uint numResults, uint serverFlags , out IIdentifyResult result);

private IIdentifyResult identifyAndWait(CoAudioIdSession session, CoAudioIdSignature signature, uint numResults, out IIdentifyResult iresult)
{
    AsyncIdentifyCaller identifyDelegate = new AsyncIdentifyCaller(session.Identify);

    IAsyncResult result = identifyDelegate.BeginInvoke(
        signature,
        numResults,
        0,
        out iresult,
        null,
        null);

    // wait up to timeout [ms] and then continue without a proper result 
    int timeout = 30000;
    result.AsyncWaitHandle.WaitOne(timeout, false);

    identifyDelegate.EndInvoke(out iresult, result);

    return iresult;
}
4

1 回答 1

1

根据我从http://msdn.microsoft.com/en-us/library/kzy257t0.aspx的理解,您应该对 WaitOne() 方法的返回值进行逻辑检查,并将您的逻辑包装起来

无论是否发生超时,您都在运行 EndInvoke,因此您会从 session.Identify 中得到相同的超时错误。

result.AsyncWaitHandle.WaitOne(timeout, false); // checks if theres is a timeout and returns true/false
identifyDelegate.EndInvoke(out iresult, result); //code to run if WaitOne returns true

你可能想要这样做:

if(result.AsyncWaitHandle.WaitOne(timeout))
{
  identifyDelegate.EndInvoke(out iresult, result);
}
else
{
  //timeout occurred
  //handle timeout
}

更新:

您可能还想查看这个 SO 线程。这个问题似乎和你的差不多。接受的答案也提供了一种可重用的方式来实现错误管理

于 2009-07-15T08:44:08.450 回答