Что не так с моим кодом 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 не поддерживается в этих потоках.
Проверьте здесь.