AsyncWaitHandle для завершения стороннего API правильно реализован? - PullRequest
0 голосов
/ 15 июля 2009

"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;
}

1 Ответ

1 голос
/ 15 июля 2009

Из того, что я могу понять из http://msdn.microsoft.com/en-us/library/kzy257t0.aspx,, вы должны провести логическую проверку возвращаемого значения метода WaitOne () и обернуть свою логику вокруг этого

Вы запускаете EndInvoke независимо от того, истекло время ожидания или нет, поэтому вы получаете те же ошибки тайм-аута из сессии. Идентифицировать.

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
}

UPDATE:

Вы также можете проверить эту ветку SO . Проблема кажется близкой к твоей. Также принятый ответ предоставляет повторно используемый способ реализации управления ошибками

...