2016-04-15 12 views
1

Ich sah Stephen Cleary's Blog über Startnew being dangerous und wie continuewith is also dangerous. Ich wollte es hier benutzen, um zu vermeiden, dass ich einen Versuch schreiben muss, um im Falle einer Ausnahme einen Anruf bei NSubstitute zu machen. Ich fand den Test bestanden, als es nicht sein sollte und bemerkte dann, dass die Ausnahme ausgelöst wurde, aber es machte es nicht aus dem Test, um Nunit zu signalisieren.Behandelt ContinueWith keine Async-Rückrufe?

Funktioniert ContinueWith in Bezug auf asynchrone Funktionen ähnlich wie Task.Startnew? Ich habe bemerkt, diese vereinfachte äquivalente nicht die innere Ausnahme in Nunit werfen 3.

[Test] 
public async Task SimpleTest() 
{ 
    await Task.Delay(10).ContinueWith(async t => 
    { 
     await Task.Run(()=>{throw new Exception();}); 
    }); 
} 

Antwort

3

ContinueWith nicht async lambdas nicht versteht. Sie müssten Unwrap zusätzlich zur Übergabe eines Task-Schedulers verwenden.

Ich wollte es hier verwenden, um zu vermeiden, einen Versuch schließlich zu schreiben, um nur im Falle einer Ausnahme zu NSubstitute aufzurufen.

Ich verstehe diese Anforderung nicht. Warum sollte das nicht funktionieren?

await Task.Delay(10); 
await Task.Run(() => { throw new Exception(); }); 
+0

In dem Beispiel war die Verzögerung nur etwas "Arbeit". Bei meinem eigentlichen Test könnte diese Arbeit eine Ausnahme auslösen, so dass ich zuerst mit einem try catch einpacken und dann NSubstitute empfangen müsste (bei einer Versprechens-Aufgabenfunktion, die abgewartet werden muss, die durch task.run in dargestellt wird mein Beispiel). Es schien so, als würde es ein bisschen mehr Code sein als continwith. – ProdigousRanger

+0

Um dies zu wiederholen, würde ein * richtiger * Aufruf von 'ContinueWith' wie folgt aussehen:' aware Task.Delay (10) .ContinueWith (_ => Task.Run (...), CancellationToken.None, TaskContinuationOptions.DenyChildAttach | TaskContinuationOptions .ExecuteSynchronously, TaskScheduler.Default) .Unwrap(); 'Ich denke' try {warte auf Task.Delay (10); } finally {warten Task.Run (...); } 'ist viel sauberer. –

+0

Wenn das der Fall ist (ich bin auf jeden Fall unwissend, wenn ich die Benutzung fortsetze), würde ich zustimmen. Ich habe am Ende eine kleine Hilfs-Bibliothek mit Hilfe von warten und versuchen/fangen/schließlich erstellen, das ist ähnlich wie JavaScript Versprechen, die mich zu etwas wie doThis.finally (somethingselse). Auf diese Weise vermeide ich continuewith und vermeiden Sie es zu versuchen, schließlich alle meine Tests zu versuchen. Danke für deine Hilfe Stephen. – ProdigousRanger