2014-05-08 3 views
5

द्वारा लौटाए गए कार्य में अधिक विवरण कैसे जोड़ें, निम्नलिखित कोड कई यूआरएल से असीमित रूप से सामग्री पुनर्प्राप्त कर रहा है, और जैसे ही एक सामग्री डाउनलोड की गई है, कार्य के लिए धन्यवाद। जब भी, तो यह संसाधित हो जाता है। लेकिन संसाधित भाग में, मुझे पहचानकर्ता वस्तु की आवश्यकता है। मुझे लगता है कि आप कोड को दिखाने के लिए स्पष्ट है:HttpClient.GetAsync

var downloadTasks = new List<Task<string>>(); 

     foreach (var identifier in input.Identifiers) 
     { 
      string url = BuildUrl(identifier, input.PeriodInYear, input.Interval); 

      var data = _webRequest.GetData(url, token); 

      downloadTasks.Add(data); // Here I only add the data, but not the Identifier. I thought about using a List<Tuple<Identifier, Task<string>>, but then I can't use it with Task.WhenAny(...) 
     } 

     while (downloadTasks.Count > 0) 
     { 
      var finishedDownloadTask = await Task.WhenAny(downloadTasks); 
      downloadTasks.Remove(finishedDownloadTask); 

      foreach (var content in await finishedDownloadTask) 
      { 
       // hereI I also need the Identifier object here ! 
      } 
     } 

यहाँ GetData का कोड:

public virtual async Task<string> GetData(string uri, CancellationToken token) 
    { 
     // log removed 
     // try catch removed 

     string result = string.Empty; 

      using (var client = new HttpClient()) 
      using (var response = await client.GetAsync(uri, token).ConfigureAwait(false)) 
      { 
       if (response.IsSuccessStatusCode) 
        result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
       else 
        logger.Error("Unable to retrieve data from the following url: {0} - StatusCode: {1}", uri, response.StatusCode); 
      } 

     return result;  
    } 

उत्तर

7

मुझे नहीं लगता कि "कार्यों की एक सूची का निर्माण" है, "await Task.WhenAny" " सूची से पूरा कार्य हटाएं "दृष्टिकोण बहुत साफ है।

मुझे लगता है कि जब मैं पीछे हटता हूं, कोड पर नज़र डालता हूं, और एक नई एसिंक्रोनस विधि लिखता हूं जो "प्रारंभिक" प्रसंस्करण के साथ-साथ "पोस्टप्रोसेसिंग" करता है तो मेरा कोड आमतौर पर क्लीनर होता है।

async Task GetDataAndPostProcessAsync(Identifier identifier, CancellationToken token) 
{ 
    var url = BuildUrl(identifier, input.PeriodInYear, input.Interval); 
    var content = await _webRequest.GetDataAsync(url, token); 
    // Use 'content' with 'identifier' 
} 

... 

var tasks = input.Identifiers.Select(identifier => 
    GetDataAndPostProcessAsync(identifier, token)).ToList(); 
await Task.WhenAll(tasks); 

मैं सी # कुकबुक में मेरी संगामिति के नुस्खा 2.6 में और अधिक विस्तार में इस कवर: अपने उदाहरण के साथ, यह कुछ इस तरह दिखेगा।

संबंधित मुद्दे