2016-04-30 12 views
4

Ich habe eine Konsole App, wo ich auf einige URL 200 mal zugreifen muss, warten auf alle Anfragen an zurückgeben und an den 200 Ergebnissen arbeiten .Zugriff auf Ergebnisse in Enumerable.Range, ohne auf alle Aufgaben warten zu müssen

Ich habe es so, parallel:

var classNameTasks = Enumerable.Range(1, 200).Select(i => webApi.getSplittedClassName()).ToArray(); 
string[][] splittedClassNames = await Task.WhenAll(classNameTasks); 
if (splittedClassNames[0] == null) 
    result = new TextResult("Error accessing the web"); 

getSplittedClassName eine string[] zurückkehrt, wenn das Internet aus ist es null zurück.

Nun, wie Sie nach der Fertigstellung aller Aufgaben sehen können, ich ein wenn den Inhalt zu überprüfen, ob seine null -> Internet-Themen.

Das Problem hier ist, dass ich warten muss, bis die ganzen 200 Anfragen zurückkommen, bevor ich den Inhalt überprüfen kann.

Ich bin auf der Suche nach einer Möglichkeit, sofort ein Szenario zu erkennen, wo es kein Internet gibt, und ich gebe null zurück, ohne auf die 200 Anfragen warten zu müssen.

+1

Haben Sie das Internet erwarten, dass die Aufgaben fallen * während der Aufgabenausführung? * Oder können Sie überprüfen, für den Internet gerade vor dem Start? –

+0

Stark verwandt: http://Stackoverflow.com/q/27238232 –

+0

Umm, ich denke, es könnte beide Optionen sein. Ich versuche nur, alle Fehler zu erfassen, die passieren können. –

Antwort

2

das Sie

  1. A CancellationTokenSource signalisieren tun müssen, dass die Arbeit erledigt ist.
  2. Die WhenAll Methode von Tortuga.Anchor

    static async Task Test() 
    { 
        TextResult result; 
    
        var cts = new CancellationTokenSource(); 
    
        var classNameTasks = Enumerable.Range(1, 200).Select(i => getSplittedClassName(cts)).ToArray(); 
        await classNameTasks.WhenAll(cts.Token); 
        if (cts.IsCancellationRequested) 
         result = new TextResult("Error accessing the web"); 
    
        string[][] splittedClassNames = classNameTasks.Select(t => t.Result).ToArray(); 
    
    } 
    
    private static async Task<string[]> getSplittedClassName(CancellationTokenSource cts) 
    { 
        try 
        { 
         //real code goes here 
         await Task.Delay(1000, cts.Token); //the token would be passed to the real web method 
         return new string[0]; 
        } 
        catch 
        { 
         cts.Cancel(); //stop trying 
         return null; 
        } 
    } 
    
+0

dies ist der richtige Ansatz, obwohl es korrekter gewesen wäre (oder - mit dem OP ausgerichtet)) wenn anstelle von try/catch block das Token abgebrochen wird im Falle einer Null-Wert-Antwort (anstatt einer Ausnahme) –

+0

Ich reparierte die Rückkehr, um null zu sein, aber ich denke, dass es noch einen Fehler gibt. Wenn ich mich nicht irre, erwartet '' classNameTasks.WhenAll (cts.Token); '' eine 'AggregateException', die eine' OperationCanceledException' enthält; –