首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多次使用AutoResetEvent

多次使用AutoResetEvent
EN

Stack Overflow用户
提问于 2013-04-11 22:13:44
回答 1查看 1.1K关注 0票数 0

在.Net 4.0Web应用程序中,我有两个对一个C#服务的异步调用。这些都是使用AutoResetEvent WaitOne()进行控制的。

在我的本地机器上,这可以正常工作。但是当我将它部署到服务器中时,在第一个调用中调用了第二步的成功处理程序。

需要做什么更改才能使线程正常运行?

代码语言:javascript
复制
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();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-12 02:33:10

如果我没看错你的代码,你有一个危险的竞态条件。您必须:

代码语言:javascript
复制
lookupServicesAssociate.SearchContactDetailsAsync(req);
autoRestEvent = new AutoResetEvent(false);
lookupServicesAssociate.SearchContactDetailsCompleted +=
    new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(AssociateSearchContactDetailsCompleted);
autoRestEvent.WaitOne();

在第一行中,调用async方法。然后,创建AutoResetEvent并分配事件处理程序。

如果SearchContactDetailsAsync在您分配回调之前完成,您的WaitOne将永远不会完成,因为回调不会执行,事件也永远不会发出信号。

你真的应该这样写:

代码语言:javascript
复制
autoRestEvent = new AutoResetEvent(false);
lookupServicesAssociate.SearchContactDetailsCompleted +=
    new EventHandler<ServiceResponseEventArgs<ContactDetailsPreview[]>>(AssociateSearchContactDetailsCompleted);
lookupServicesAssociate.SearchContactDetailsAsync(req);
autoRestEvent.WaitOne();

尽管老实说,我想知道为什么你要启动一个异步任务,然后等待它的完成。你实际上是在同步做这件事。

话虽如此,我不得不同意帕科的评论:除非UserID == null,否则这是不可能发生的。这引发了另一个潜在的问题:如果autoResetEventnullUserID == null,那么第二个WaitOne将抛出NullReferenceException。如果多个线程正在执行这段代码,每个线程将创建一个不同的AutoResetEvent,这肯定会导致问题,因为您可能会等待一个永远不会发出信号的事件,或者等待错误的事件并捕获其他人的信号。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15951092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档