简体   繁体   English

如何确定一整批异步请求是否失败?

[英]How to determine if a complete batch of Async requests have failed?

A 3rd party has supplied an interface which allows me to search their database for customers and retrieve their details. 第三方提供了一个界面,该界面使我可以在其数据库中搜索客户并检索其详细信息。 Eg. 例如。 Pictures, date of birth etc. 图片,出生日期等

I imported their WSDL into Visual Studio and am using the Async methods to retrieve the customer details. 我将其WSDL导入到Visual Studio中,并且正在使用Async方法来检索客户详细信息。

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

Client.FindCustomersAsync("Jones");

Below are the two events which deal with the responses. 以下是处理响应的两个事件。

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.
}

So lets assume that my initial search for "Jones" returns no results or causes an error. 因此,假设我最初搜索“ Jones”不返回任何结果或导致错误。 Its fairly straight forward to tell the user that there was an error or no results found as I will only receive a single response. 告诉用户存在错误或没有找到结果是相当直接的,因为我只会收到一个响应。

However if i say get 50 results for "Jones" then i make 50 GetCustomerDetailsAsync calls and get 50 responses. 但是,如果我说“琼斯”获得50个结果,那么我将进行50个GetCustomerDetailsAsync调用并获得50个响应。

Lets say that something goes wrong on the server side and i don't get any valid responses. 可以说服务器端出了问题,我没有得到任何有效的响应。 Each GetCustomerDetailsCompleted event will receive an error/timeout and i can determine that that individual response has failed. 每个GetCustomerDetailsCompleted事件都会收到一个错误/超时,我可以确定该单个响应已失败。

What is the best way to determine that All of my responses have failed and i need to inform the user that there has been a failure? 确定我的所有响应都失败并且我需要通知用户失败的最佳方法是什么? Alternatively what if 1 out of 50 succeeds? 或者,如果50分之一成功了怎么办?

Should i keep track of my requests and flag them as successful as i receive the response? 我应该跟踪我的请求并在收到响应后将其标记为成功吗?

Should i keep track of my requests and flag them as successful as i receive the response? 我应该跟踪我的请求并在收到响应后将其标记为成功吗?

This is also how I manage multiple requests. 这也是我管理多个请求的方式。 Flag if the returned result is without fault and track the flags, evaluating after each return if you already processed all returns. 如果返回的结果没有问题,则进行标记并跟踪这些标记,如果已处理所有返回,则在每次返回之后进行评估。 I do not of another way. 我没有别的办法。

I would start by converting Event-based Asynchronous Pattern model to Task based. 我将从将基于事件的异步模式模型转换为基于任务开始。 This would allow to use built in await/async keywords resulting in much easier to use code. 这将允许使用内置的await / async关键字,从而使代码更易于使用。

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

In your case I would not update UI on each event but gathered all the information in a single variable and only displayed only when I get all the results. 在您的情况下,我不会在每个事件上更新UI,而是将所有信息收集在一个变量中,并且仅在获得所有结果时才显示。

Here is a code to get you going: 这是让您开始的代码:

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;
    }
}

Then you call this by: 然后通过以下方式调用此方法:

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

This would fail if any request fails. 如果任何请求失败,这将失败。

PS. PS。 I wrote this example in notepad, so bear with me if it does not compiles or contains syntax errors. 我在记事本中编写了此示例,所以如果它不编译或包含语法错误,请多多包涵。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM