views:

143

answers:

1

Hi,

"session.identify" is a third party COM API that I call and have no access to. It performs a server query that, somehow, locks up occasionally (and thus halts the main program which is waiting for the result).

My attempt was to wrap it in an AsyncDelegate so I would be able to give it a timeout and after expiration of the timeout allow the main program to proceed (similar to this one, just with a return value). However, it still locks up without the timeout having an effect.

Am I using the AsyncHandle.WaitOne incorrectly? Could there be something in the API that prevents it from being aborted?

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  A: 

From what I can understand from http://msdn.microsoft.com/en-us/library/kzy257t0.aspx, you should have a logical check on the return value of WaitOne() method and wrap your logic around that

You're running the EndInvoke regardless if a timeout ocurrs or not, thus you're getting the same timout errors from 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

You'd probably want to do this:

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

UPDATE:

You might also like to check out this SO thread. The problem seems close to identical to yours. Also the accepted answer supplies a re-usable way to implement error-management

pavsaund
I changed it to your suggestion with a 10 sec timeout. The query still locks up occasionally, but the timeout condition is never reached. What could prevent the WaitHandle from doing its job?
Hauke
The system behaves the same as calling session.identify directly.
Hauke
I see. I believe that you have may have to forcibly abort the thread that is taking too long to respond, so that you can get along with your app. I'll update my answer
pavsaund