c# - 当所有异步方法调用完成时引发事件

标签 c# wcf events asynchronous

我有以下问题: 在异步上下文中,我需要先初始化一些自定义对象的字段,然后才能继续对其进行其他操作,所以我这样做:

class ContainingObject
{    
   private CustomObject _co;

   SomeMethod()
   {
     _co = new CustomObject();
     _co.InitObjectAsyncCompleted += (s,e) => DoStuff();
     _co.InitObjectAsync();
   }    
}

class CustomObject
{
   public string Field1, Field2, Field3, Field4;

   public EventHandler InitObjectAsyncCompleted;

   public void InitObjectAsync()
   {
   }    
}

要注意的是,字段也通过异步调用 WCF 服务进行初始化,并且所有字段都必须在引发 InitObjectAsyncCompleted 事件之前进行初始化。 有很多这样的字段,每个字段都是用不同的 WCF 调用初始化的,这意味着我现在不能更改 WCF 部分,我看到两种解决问题的方法:

1) 链式 WCF 调用,因此首先调用初始化第一个字段,然后调用 WCF 初始化第二个字段,依此类推,然后再初始化所有字段,然后我在最后一个 WCF 调用中引发“完成”事件。

public void InitObjectAsync()
{  
    var proxy = new ProxyFactory.GetCustomObjectProxy;
    proxy.GetDataForField1Completed += (s,e) => 
    { 
        Field1 = e.Result;
        proxy.GetDataForField2Completed += (s1,e1) => 
        { 
          Field2 = e1.Result; 
          //keep this up building a chain of events, when Field4 is filled, raise
          // InitObjectAsyncCompleted(this, null);          
        };
        proxy.GetDataForField2();
    };
    proxy.GetDataForField1();
} 

2) 因为我知道应该完成多少方法调用,在这种情况下是 4,我可以做一个计数器。

public void InitObjectAsync()
{  
    int counter = 0;
    var proxy = new ProxyFactory.GetCustomObjectProxy;
    proxy.GetDataForField1Completed += (s,e) => 
    { 
        Field1 = e.Result;
        if(counter >= 3)
            InitObjectAsyncCompleted(this, null);
        else
            counter++;
    };
    proxy.GetDataForField1();
    proxy.GetDataForField2Completed += (s,e) => 
    { 
        Field2 = e.Result;
        if(counter >= 3)
            InitObjectAsyncCompleted(this, null);
        else
            counter++;
    };
    proxy.GetDataForField2();
    //repeat for all fields
}

我真的不喜欢这两种解决方案,第一个构建了一个相当大且可读性差的事件链,第二个只是......粗糙 - 谁能提出解决这个问题的更优雅的方法?

最佳答案

如果您使用 .NET 4.0 的并行扩展,您可以创建多个异步任务并非常轻松地加入它们:

Task[] tasks = new Task[3]
{
    Task.Factory.StartNew(() => MethodA()),
    Task.Factory.StartNew(() => MethodB()),
    Task.Factory.StartNew(() => MethodC())
};

//Block until all tasks complete.
Task.WaitAll(tasks);

关于c# - 当所有异步方法调用完成时引发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3668465/

相关文章:

c# - SSL WCF "Could not establish trust relationship for the SSL/TLS secure channel with authority ' 本地主机'

apache-flex - Flex - ResizeEvent.RESIZE 的问题

c# - 如何使用正则表达式将字符串拆分为数字和字母

c# - OleDB 查询中的格式化日期

javascript - angular.js 调用 ajax 兼容的 WCF 服务

.net - Silverlight、EDM/LINQ 和 WCF Web 服务 - 如何将集合传递给 Silverlight

javascript - 如何防止事件处理程序在 javascript 中一次处理多个事件?

java - MouseAdapter 中 isPopupTrigger() 的正确处理是什么

c# - WPF TreeView HierarchicalDataTemplate - 绑定(bind)到具有多个子集合的对象

c# - 如何在 .NET Core 中使用 HttpWebResponse 和 WebResponse?