Meine Anwendung ist über TCP/IP-Protokoll und COM-Ports an viele externe Geräte angeschlossen. Die Hauptlogik befindet sich in der Klasse MainController
(implementiert als endlicher Automat), die Signale von externen Geräten abhört und Befehle an sie sendet.Wie synchrone Methode asynchron auszuführen und auf Ergebnis warten
Immer wenn MainController
ein externes Signal empfängt, meldet es die GUI mit einem Ereignis, zum Beispiel OnSensor1Received
, OnSensor2Received
, ... damit ich ein Symbol oder eine Nachricht oder was auch immer anzeigen kann. Die gleiche Logik gilt für die andere Richtung - wenn MainController
ein Signal an ein externes Gerät sendet, wird ein Ereignis ausgelöst und etwas wird in der GUI angezeigt.
Bis hier ist die gesamte Kommunikation asynchron (wenn das der richtige Begriff ist?). Das heißt, ich erhalte Ereignisse und verarbeite sie und ich befehle Befehle, warte aber nie auf die Rückkehr in derselben Operation (man könnte sagen, dass alle Methoden zum Senden von Befehlen ungültig sind).
Aber jetzt muss ich neues Gerät hinzufügen, das nur eine öffentliche Methode hat int Process(string input, out string output)
. Die Ausführung der Methode kann einige Sekunden dauern und in der Zwischenzeit wartet der gesamte andere Code - wenn beispielsweise während der Ausführung dieser Methode ein Signal von einem anderen externen Gerät kommt, wird die GUI erst nach der Blockierung aktualisiert Methode Write
wird ausgeführt. Wie kann ich die Write
-Methode asynchron ausführen lassen, damit die GUI alle anderen Signale in Echtzeit anzeigt?
Codebeispiel wird diese irgendwo in den MainController
aufgerufen, wenn ich versuche, um das neue Gerät zu verwenden:
// Notify GUI that the blocking plugin was activated.
OnBlockingPluginActive(this, EventArgs.Empty);
string result;
// Here is the problem - during the execution of this method the GUI is not responding for other signals.
var status = blockingPlugin.Process(input, out result);
if (status == 0)
{
// OK, notify GUI and fire a BlockingPluginOK command in finite state machine.
OnBlockingPluginOK(this, EventArgs.Empty);
}
else
{
// Error, notify GUI and fire a BlockingPluginError command in finite state machine.
OnBlockingPluginError(this, EventArgs.Empty);
}
Bitte beachten Sie auch, dass ich .net 4.0 verwenden und nicht auf 4.5 aktualisieren, so dass keine native Unterstützung für async/erwarten.
Sie van try this: [ https://www.nuget.org/packages/Microsoft.Bcl.Async/1.0.16](https://www.nuget.org/packages/Microsoft.Bcl.Async/1.0.16) – Fabio
Wenn Sie noch sind mit .NET 4.0, verwenden Sie einfach Task.Factory.StartNew und verwenden .ContinueWith –
"ein paar Sekunden" ist kein vernünftiges Verhalten. Sie können den Anruf in einen Worker-Thread verschieben, aber Sie werden ihn einfach weiterleiten und blockieren. Entweder ist diese Bibliothek drastisch borken oder es verhält sich gerade jetzt aufgrund von Umweltproblemen nicht korrekt. Sie werden es nicht besser machen, indem Sie versuchen, das Problem zu umgehen, den Autor der Bibliothek um Rat fragen. –