Ich bin auf ein Problem mit einem Komponententest gestoßen, der fehlgeschlagen ist, weil ein TPL-Task seinen ContinueWith(x, TaskScheduler.FromCurrentSynchronizationContext())
nie ausgeführt hat.Warum kann Task.ContinueWith in diesem Komponententest nicht ausgeführt werden?
Das Problem stellte sich heraus, weil ein Winforms UI Control versehentlich erstellt wurde, bevor der Task gestartet wurde.
Hier ist ein Beispiel, das es reproduziert. Wenn Sie den Test unverändert ausführen, wird er ausgeführt. Wenn Sie den Test mit der unkommentierten Form-Zeile ausführen, schlägt er fehl.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
// Create new sync context for unit test
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
var waitHandle = new ManualResetEvent(false);
var doer = new DoSomethinger();
//Uncommenting this line causes the ContinueWith part of the Task
//below never to execute.
//var f = new Form();
doer.DoSomethingAsync(() => waitHandle.Set());
Assert.IsTrue(waitHandle.WaitOne(10000), "Wait timeout exceeded.");
}
}
public class DoSomethinger
{
public void DoSomethingAsync(Action onCompleted)
{
var task = Task.Factory.StartNew(() => Thread.Sleep(1000));
task.ContinueWith(t =>
{
if (onCompleted != null)
onCompleted();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
Kann mir jemand erklären, warum dies der Fall ist?
dachte ich es, weil die falsch gewesen sein könnteSynchronizationContext
verwendet wird, aber tatsächlich, die ContinueWith
nie überhaupt ausgeführt wird! Und außerdem ist in diesem Komponententest, ob es richtig ist oder nicht SynchronizationContext
ist irrelevant, denn solange der waitHandle.set()
auf einem Thread aufgerufen wird, sollte der Test bestehen.
Tritt eine Ausnahme auf? –
@SriramSakthivel Stupid Frage - Sie haben versucht mit der 'var f = new Form();' UNkommentiert? Ich ein MsTest, VS2013u4, Win8.1, Net 4.5.1 – OffHeGoes
@OffHeGoes Sorry, dass ich das übersehen. Schreibe jetzt eine Antwort :) –