【问题标题】:How to determine if a complete batch of Async requests have failed?如何确定一整批 Async 请求是否失败?
【发布时间】:2015-04-24 11:21:41
【问题描述】:

第 3 方提供了一个界面,允许我在他们的数据库中搜索客户并检索他们的详细信息。例如。图片,出生日期等。

我将他们的 WSDL 导入 Visual Studio,并使用 Async 方法检索客户详细信息。

MyClient Client = new MyClient();
Client.FindCustomersCompleted += FindCustomersCompleted;
Client.GetCustomerDetailsCompleted += GetCustomerDetailsCompleted;

Client.FindCustomersAsync("Jones");

以下是处理响应的两个事件。

void FindCustomersCompleted(object sender, FindCustomersCompletedEventArgs e)
{
    foreach(var Cust in e.Customers)
    {
        Client.GetCustomerDetailsAsync(Cust.ID);
    }
}

void GetCustomerDetailsCompleted(object sender, GetCustomerDetailsCompletedEventArgs e)
{
    // Add the customer details to the result box on the Window.
}

假设我对“Jones”的初始搜索没有返回任何结果或导致错误。告诉用户有错误或没有找到结果是相当直接的,因为我只会收到一个响应。

但是,如果我说为“Jones”获得 50 个结果,那么我会进行 50 个 GetCustomerDetailsAsync 调用并获得 50 个响应。

假设服务器端出了点问题,我没有得到任何有效的响应。每个 GetCustomerDetailsCompleted 事件都将收到错误/超时,我可以确定该单个响应已失败。

确定我的所有响应都失败并且我需要通知用户失败的最佳方法是什么? 或者,如果 50 人中有 1 人成功了怎么办?

我是否应该跟踪我的请求并在收到响应时将它们标记为成功?

【问题讨论】:

    标签: c# asynchronous error-handling wsdl


    【解决方案1】:

    我是否应该跟踪我的请求并将它们标记为成功? 收到回复了吗?

    这也是我管理多个请求的方式。如果返回的结果没有错误,则标记并跟踪标记,如果您已经处理了所有返回,则在每次返回后评估。我不采取另一种方式。

    【讨论】:

      【解决方案2】:

      我首先将基于事件的异步模式模型转换为基于任务的模型。这将允许使用内置的 await/async 关键字,从而使代码更易于使用。

      这是一个简单的实现:https://stackoverflow.com/a/15316668/3070052

      在您的情况下,我不会更新每个事件的 UI,而是将所有信息收集在一个变量中,并且仅在获得所有结果时才显示。

      这里有一段代码可以帮助你:

      public class CustomerDetails
      {
          public int Id {get; set;}
          public string Name {get; set;}
      }
      
      public class FindCustomersResult
      {
          public FindCustomersResult()
          {
              CustomerDetails = new List<CustomerDetails>();
          }
          public List<CustomerDetails> CustomerDetails {get; set;}
      }
      
      public class ApiWrapper
      {
          public Task<FindCustomersResult> FindCustomers(string customerName)
          {
              var tcs = new TaskCompletionSource<FindCustomersResult>(); 
              var client = new MyClient();
              client.FindCustomersCompleted += (object sender, FindCustomersCompletedEventArgs e) => 
                  {
                      var result = new FindCustomersResult();
      
                      foreach(var customer in e.Customers)
                      {
                          var customerDetails = await GetCustomerDetails(customer.ID);
                          result.CustomerDetails.Add(customerDetails);
                      }
                      tcs.SetResult(result);
                  }
              client.FindCustomersAsync(customerName);    
              return tcs.Task;
          }
      
          public Task<CustomerDetails> GetCustomerDetails(int customerId)
          {
              var tcs = new TaskCompletionSource<CustomerDetails>(); 
              var client = new MyClient();
              client.GetCustomerDetailsCompleted += (object sender, GetCustomerDetailsCompletedEventArgs e) => 
                  {
                      var result = new CustomerDetails();
                      result.Name = e.Name;
                      tcs.SetResult(result);
                  }
              client.GetCustomerDetailsAsync(customerId); 
              return tcs.Task;
          }
      }
      

      然后你调用它:

      var api = new ApiWrapper();
      var findCustomersResult = await api.FindCustomers("Jones");
      

      如果任何请求失败,这将失败。

      附言。我在记事本中写了这个例子,所以如果它没有编译或包含语法错误,请多多包涵。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-06
        • 2022-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多