Что не так с моим кодом AutoResetEvent?

У меня есть этот код, который кажется довольно простым, но AutoResetEvent никогда не получает сигнал. Кажется, что ничего не возвращается из веб-сервисов, и через десять секунд WaitAll просто отключается. Все отлично работает без jiggerypokery потоков, так что это не проблема веб-службы. Что я делаю неправильно?

    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();
    }

3 ответа

Я могу предложить наивное первое предположение: похоже, вы добавляете обработчики событий после вызова методов, запускающих асинхронные операции; возможно, там есть состояние гонки или другая проблема. Не могли бы вы изменить порядок операций, чтобы прикрепить обработчик событий, а затем начать операцию?

Это объекты AutoResetEvent - похоже, что вы хотите ManualResetEvent - автоматическая версия вызывает все, что ждет, но немедленно сбрасывается. Ручные остаются активированными, поэтому, если обратный вызов произойдет до того, как вы попадете в WaitAll, он сразу же провалится.

Кроме того, qid верен - вы слишком поздно подключаете свои обработчики событий... поэтому здесь происходят две разные ошибки.

Используете ли вы этот код в потоке, помеченном атрибутом STA, например в основном потоке пользовательского интерфейса? Если это так, метод WaitAll не поддерживается в этих потоках.

Проверьте здесь.

Другие вопросы по тегам