2017-05-26 2 views
2

Haben Sie eine Frage über den richtigen Weg zur sofortigen Beendigung der Aufgabe. Zum Beispiel habe ich den folgenden Code:Was ist der richtige Weg zum Beenden von Aufgaben?

public async Task<string> DoAsync() 
{ 
    var result = await Task.Run(() => 
    { 
     //Some heavy request here in a row (5 seconds per request) 
     DoHeavyRequest(); // 1 
     DoHeavyRequest(); // 2 
     DoHeavyRequest(); // 3 
     DoHeavyRequest(); // 4 

     return "success"; 
    }); 

    return results; 
} 

Wie ich diese Aufgabe in einem Moment abbrechen? Zum Beispiel, ich führe die Aufgabe für 7 Sekunden, ich erwarte, dass nur erste und wahrscheinlich zweite "schwere Anfragen" würde aufgerufen werden, 3-4 werden überhaupt nicht aufgerufen werden.

Vielen Dank im Voraus.

+4

'CancellationTokenSource',' CancellationToken'? –

+4

Sie können es nicht einfach beenden. Sie sollten eine kooperative Kündigung mit 'CancellationToken' und Freunden verwenden. – Evk

Antwort

2

Ich schlage vor, Stornierung:

public async Task<string> DoAsync(CancellationToken token) { 
    var result = await Task.Run(() => { 
    //TODO: you may want to pass token to DoHeavyRequest() and cancel there as well 
    token.ThrowIfCancellationRequested(); 
    DoHeavyRequest(); // 1 

    token.ThrowIfCancellationRequested(); 
    DoHeavyRequest(); // 2 

    token.ThrowIfCancellationRequested(); 
    DoHeavyRequest(); // 3 

    token.ThrowIfCancellationRequested(); 
    DoHeavyRequest(); // 4 

    return "success"; 
    }); 

    return "results"; 
} 

// Let's preserve the current interface - call without cancellation 
public async Task<string> DoAsync() { 
    return await DoAsync(CancellationToken.None); 
} 

...

// Run, wait up to 7 seconds then cancel 
try { 
    using (CancellationTokenSource cts = new CancellationTokenSource(7000)) { 
    // Task completed, its result is in the result 
    string result = await DoAsync(cts.Token); 

    //TODO: Put relevant code here 
    } 
catch (TaskCanceledException) { 
    // Task has been cancelled (in this case by timeout) 

    //TODO: Put relevant code here 
} 
Verwandte Themen