Ich verwende Aufgaben , um lange laufende Serveraufrufe in meinem ViewModel auszuführen, und die Ergebnisse werden bei Dispatcher
Verwendung wieder zusammengeführt TaskScheduler.FromSyncronizationContext()
. Beispielsweise:
var context = TaskScheduler.FromCurrentSynchronizationContext();
this.Message = "Loading...";
Task task = Task.Factory.StartNew(() => { ... })
.ContinueWith(x => this.Message = "Completed"
, context);
Dies funktioniert gut, wenn ich die Anwendung ausführe. Wenn ich meine NUnit
Tests jedoch ausführe, wird Resharper
beim Aufruf die folgende Fehlermeldung angezeigt FromCurrentSynchronizationContext
:
Der aktuelle SynchronizationContext darf nicht als TaskScheduler verwendet werden.
Ich denke, das liegt daran, dass die Tests auf Arbeitsthreads ausgeführt werden. Wie kann ich sicherstellen, dass die Tests im Hauptthread ausgeführt werden? Alle anderen Vorschläge sind willkommen.
TaskScheduler.FromCurrentSynchronizationContext()
in einem Lambda verwendet und die Ausführung wurde auf einen anderen Thread verschoben. Das Problem wurde behoben, indem der Kontext außerhalb von Lambda abgerufen wurde.Antworten:
Sie müssen einen SynchronizationContext angeben. So gehe ich damit um:
quelle
TestInitializeAttribute
, sonst besteht nur der erste Test.Die Lösung von Ritch Melton hat bei mir nicht funktioniert. Dies liegt daran, dass meine
TestInitialize
Funktion asynchron ist, ebenso wie meine Tests, sodass bei jedemawait
der StromSynchronizationContext
verloren geht. Dies liegt daran, dass, wie MSDN hervorhebt, dieSynchronizationContext
Klasse, "dumm" ist und nur alle Arbeiten an den Thread-Pool in die Warteschlange stellt.Was für mich funktioniert hat, ist, den
FromCurrentSynchronizationContext
Anruf einfach zu überspringen , wenn es keinen gibtSynchronizationContext
(dh wenn der aktuelle Kontext null ist ). Wenn es keinen UI-Thread gibt, muss ich ihn überhaupt nicht synchronisieren.Ich fand diese Lösung einfacher als die Alternativen, bei denen:
TaskScheduler
an das ViewModel (über Abhängigkeitsinjektion)SynchronizationContext
und einen "gefälschten" UI-Thread, damit die Tests ausgeführt werden können - viel mehr Ärger für mich, als es wert istIch verliere einen Teil der Threading-Nuance, teste jedoch nicht explizit, ob meine OnPropertyChanged-Rückrufe für einen bestimmten Thread ausgelöst werden, daher bin ich damit einverstanden. Die anderen Antworten, die mit
new SynchronizationContext()
verwendet werden, sind für dieses Ziel sowieso nicht wirklich besser.quelle
else
Fall wird auch in einer Windows-Service-App fehlschlagen, was dazu führtsyncContextScheduler == null
[RequiresThread]
Attribut zu markieren .Ich habe mehrere Lösungen kombiniert, um die Funktionsfähigkeit von SynchronizationContext zu gewährleisten:
Verwendung:
quelle