views:

121

answers:

3

Hi, I have this code which seems pretty straightforward but the AutoResetEvent never gets signalled. Nothing seems to get returned from the web services and the WaitAll just times out after ten seconds. Everything works fine without the threading jiggerypokery so its not a web service issue. What am I doing wrong?

    AutoResetEvent[] autoEvents;
    ObservableCollection<Tx3.ResourceService.ResourceTime> resourceTime;
    ObservableCollection<Tx3.ResourceService.ResourceTimeDetail> resourceTimeDetail;

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        autoEvents = new AutoResetEvent[]
        {
            new AutoResetEvent(false),
            new AutoResetEvent(false),
        };

        var resourceService = getResourceServiceClient();

        // Get ResourceTime data for this user
        resourceService.ListResourceTimeAsync(CategoryWorkItemId, ResourceId);
        resourceService.ListResourceTimeCompleted += new EventHandler<Tx3.ResourceService.ListResourceTimeCompletedEventArgs>(resourceService_ListResourceTimeCompleted);

        // Get ResourceTimeDetails
        resourceService.ListResourceTimeDetailAsync(CategoryWorkItemId, ResourceId);
        resourceService.ListResourceTimeDetailCompleted += new EventHandler<ListResourceTimeDetailCompletedEventArgs>(resourceService_ListResourceTimeDetailCompleted);

        WaitHandle.WaitAll(autoEvents, 10000);

        System.Diagnostics.Debug.WriteLine("do something with both datasets");
    }

    void resourceService_ListResourceTimeCompleted(object sender, Tx3.ResourceService.ListResourceTimeCompletedEventArgs e)
    {
        resourceTime = e.Result;
        autoEvents[0].Set();
    }

    void resourceService_ListResourceTimeDetailCompleted(object sender, ListResourceTimeDetailCompletedEventArgs e)
    {
        resourceTimeDetail = e.Result;
        autoEvents[1].Set();
    }
+2  A: 

I can offer a naive first guess: it looks like you're adding the event handlers after calling the methods that start the asynchronous operations; it's possible there's a race condition in there or some other issue. Could you switch the order of operations so you attach the event handler, and then begin the operation?

qid
What a silly sausage(!) Lets assume I've written the handlers the correct way around.
Paul
Okay, I've tried correcting the handlers... same problem.
Paul
If this is a web service, you should be able to rig up Wireshark and verify whether it's working correctly; can you verify that the responses are coming back? If they are, try setting breakpoints in the callback methods and see if you make it there. Basically just try to check every step along the way that you can until you see where it falls apart.
qid
Theres nothing wrong with the web services, they terminate correctly if I remove all the autoevent stuff... just not synced.
Paul
+1  A: 

These are AutoResetEvent objects -- looks like you want a ManualResetEvent -- the auto version triggers anything waiting, but immediately resets. Manual ones stay triggered so if the callback happens before you get to the WaitAll, it'll just fall through immediately.

Also, qid is correct -- you're attaching your event handlers too late too...so there's two different bugs going on here.

Clyde
I thought that might be the case too - but according to the MSDN docs the event is reset only after it signals a thread.
Aaron
Oh, you're right -- silly me. qid likely has the answer, then
Clyde
Okay, I've tried correcting the handlers... same problem.
Paul
+1  A: 

Are you using this code on a thread that is marked with the STA attribute, for example the main UI thread? If so, the WaitAll method is not supported on these threads.

Check here.

Andy