2013-04-11 4 views
0

У меня есть два асинхронных вызова одной веб-службы в приложении .NET 4.0 C#. Они управляются с помощью AutoResetEvent WaitOne().Использование AutoResetEvent несколько раз

У меня на локальном компьютере это работает как ожидается. Но когда я развернул его на сервере, в первом вызове вызывается обработчик второго шага.

Какие изменения необходимо сделать для правильной работы нити?

if (userID != null) 
{ 
    AddressBookRequest req = new AddressBookRequest 
    { 
     contactsSearchCriteria = new ContactsSearchCriteria 
     { 
      searchUserID = userID.Trim() 
     }, 
     HeaderParams = new HttpHeaderParms 
     { 
      UserId = userID.Trim(), 
      UserPrincipalName = userID.Trim() , 
      ContentType = "application/xml" 
     } 
    }; 
    lookupServicesAssociate.SearchContactDetailsAsync(req); 
    autoRestEvent = new AutoResetEvent(false); 
    lookupServicesAssociate.SearchContactDetailsCompleted += 
     new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(AssociateSearchContactDetailsCompleted); 
    autoRestEvent.WaitOne(); 
} 

if (reportsToUserID != null) 
{ 
    AddressBookRequest req1 = new AddressBookRequest 
    { 
     contactsSearchCriteria = new ContactsSearchCriteria 
     { 
      searchUserID = reportsToUserID.Trim() 
     }, 
     HeaderParams = new HttpHeaderParms 
     { 
      UserId = reportsToUserID.Trim(), 
      UserPrincipalName = reportsToUserID.Trim(), 
      ContentType = "application/xml" 
     } 
    }; 
    lookupServiceReports.SearchContactDetailsAsync(req1); 
    lookupServiceReports.SearchContactDetailsCompleted += 
     new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(ReportsToAssociateSearchContactDetailsCompleted); 
    autoRestEvent.WaitOne(); 
} 
+0

Что означает «обработчик успеха второго шага в первом вызове» означает? Какова область действия 'autoRestEvent' и какой код вызывает метод' Set'? Если вы ждете ответа на вызовы веб-службы, почему вы вызываете их асинхронно? – Igor

+0

@Igor autoRestEvent находится на уровне класса. 'Set' вызывается обработчиками успеха. Это существующий асинхронный сервис. Я не контролирую службу – Lijo

+2

Являются ли условия и тестовые данные на сервере такими же, как на вашем локальном компьютере? Может быть, я что-то упустил, но он выглядит нормально, и единственная причина, почему «ReportToAssociateSearchContactDetailsCompleted» вызывается первым, - это первый оператор 'if', который возвращает' false' – Pako

ответ

2

Если я правильно читаю ваш код, у вас есть опасное состояние гонки. У вас есть:

lookupServicesAssociate.SearchContactDetailsAsync(req); 
autoRestEvent = new AutoResetEvent(false); 
lookupServicesAssociate.SearchContactDetailsCompleted += 
    new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(AssociateSearchContactDetailsCompleted); 
autoRestEvent.WaitOne(); 

В первой строке вы вызываете метод async. Затем вы создаете AutoResetEvent и назначаете обработчик событий.

Если SearchContactDetailsAsync должно было быть выполнено до того, как вы назначили обратный вызов, ваш WaitOne никогда не завершится, потому что обратный вызов не будет выполнен, и событие никогда не будет сигнализировано.

Вы действительно должны написать:

autoRestEvent = new AutoResetEvent(false); 
lookupServicesAssociate.SearchContactDetailsCompleted += 
    new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(AssociateSearchContactDetailsCompleted); 
lookupServicesAssociate.SearchContactDetailsAsync(req); 
autoRestEvent.WaitOne(); 

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

Все, что сказал, я должен согласиться с комментарием Пако: этого не может быть, если UserID == null. Что вызывает еще одну потенциальную проблему: если autoResetEvent - null и UserID == null, второй WaitOne собирается бросить NullReferenceException. И если несколько потоков выполняли этот код, каждый из них собирается создать другой AutoResetEvent, который наверняка вызовет проблемы, потому что вы можете закончить ожидание события, которое никогда не будет сигнализироваться, или ждать неправильного события и захватив чужой сигнал.

Смежные вопросы