在.Net 4.0Web应用程序中,我有两个对一个C#服务的异步调用。这些都是使用AutoResetEvent WaitOne()进行控制的。
在我的本地机器上,这可以正常工作。但是当我将它部署到服务器中时,在第一个调用中调用了第二步的成功处理程序。
需要做什么更改才能使线程正常运行?
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();
}发布于 2013-04-12 02:33:10
如果我没看错你的代码,你有一个危险的竞态条件。您必须:
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,这肯定会导致问题,因为您可能会等待一个永远不会发出信号的事件,或者等待错误的事件并捕获其他人的信号。
https://stackoverflow.com/questions/15951092
复制相似问题