问题
I have an asyncronous task that goes out to several websites parses some data and returns the data when its finished. In the event that one or more of the websites fail - I need to find out which ones failed. Is this possible? Here is some example code I have:
The controller
public async Task<ActionResult> Index()
{
Models.WebSite ws = new Models.WebSite();
List<Task<string>> webList = new List<Task<string>>();
webList.Add(ws.GetWebsiteInfoAsync("http://website1.com"));
webList.Add(ws.GetWebsiteInfoAsync("http://website2.com"));
webList.Add(ws.GetWebsiteInfoAsync("http://website3.com"));
var taskComplete = await Task.WhenAll(webList);
return View(taskComplete);
}
The class that makes the web requests:
public async Task<string> GetWebsiteInfoAsync(string url)
{
System.Net.WebClient wc = new System.Net.WebClient();
string result = null;
result = await wc.DownloadStringTaskAsync(new Uri(url));
return result;
}
回答1:
You can examine the individual tasks (that you are storing in a list at the moment). Examine their properties, such as Status
or IsFaulted
.
As soon as taskComplete
has completed, all individual website tasks will have completed as well. So await
taskComplete
, swallow the resulting exception and examine the website tasks.
回答2:
I would create a request/result class that holds the URL and the result and then pass an instance of this class to the Async request.
Once all tasks are done, you can cycle through the list of requests and, if the result indicates failure, present a comprehensive list to the user.
For example, the class:
public class URLRequest
{
public URLRequest(string url)
{
Url = url;
}
public string Url{get;set;}
public string Result { get; set; }
}
You can then create a list of the requests and use these to fire the async requests:
var requests = new List<URLRequest>();
requests.Add(new URLRequest("http://website1.com"));
requests.Add(new URLRequest("http://website2.com"));
requests.Add(new URLRequest("http://website3.com"));
foreach (var request in requests) {
webList.Add(ws.GetWebsiteInfoAsync(request));
}
The async method would be modified to use the URL and result from the request object:
public async Task<string> GetWebsiteInfoAsync(URLRequest request)
{
System.Net.WebClient wc = new System.Net.WebClient();
string result = null;
request.Result = await wc.DownloadStringTaskAsync(new Uri(request.Url));
return request.result;
}
Then you could report the results by looping through the requests again:
var message = new StringBuilder(500);
foreach (var request in requests) {
if (!string.IsNullOrEmpty(request.Result)) {
if (message.Length == 0) {
message.Append("Sorry, the following website(s) failed: ");
} else {
message.Append(", ");
}
message.Append(request.Url);
}
}
Note that testing the result is only an example; if you want to catch exceptions or use another mechanism to indicate failure, then you can simply modify the request class and the async code.
来源:https://stackoverflow.com/questions/20808075/how-to-find-out-which-of-these-sites-failed