0

「session.identify」は、私が呼び出してアクセスできないサードパーティの COM API です。サーバークエリを実行すると、何らかの理由で時々ロックアップします (その結果、結果を待っているメインプログラムが停止します)。

私の試みはそれを AsyncDelegate でラップすることでしたので、タイムアウトを与えることができ、タイムアウトの期限が切れた後、メインプログラムを続行できます(これと同様に戻り値のみで)。ただし、タイムアウトが影響を与えずにロックアップします。

AsyncHandle.WaitOne を間違って使用していますか? API が中止されないようにする何かが 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 に答える