2016-05-16 28 views
0

Ich schreibe ein Programm, das mit der von mir entwickelten Steuerungshardware kommuniziert. Die Hardware treibt Motoren und das erste, was ich damit machen will, ist einen Motor zu initialisieren. Die Hardware ist kommunikationsgesteuert. Um alles zu tun, sende ich einfach eine Nachricht über USB an die Hardware. Um einen Motor zu initialisieren, muss ich 2 Nachrichten senden; nachdem ich den ersten gesendet habe, bewegt er den Motor zu einem Sensor, und wenn er ihn erreicht, stoppt er und sendet mir eine Nachricht zurück, die mir sagt, dass er angehalten hat. An diesem Punkt sende ich ihm eine weitere Nachricht, dass er den Motor antreiben soll die entgegengesetzte Richtung sehr langsam, bis es aus dem Sensor kommt.Verwenden Sie async/await oder etwas anderes

Alle meine Kommunikation ist in einem SerialPortDataReceived Ereignis. Wie kann ich am besten auf die entsprechende Nachricht warten und dann die zweite Nachricht senden? Im Moment verwende ich einfach eine Eigenschaft vom Typ bool, die ich vor der Initialisierung auf true gesetzt habe, und dann in meinem Event-Handler, wenn ich die Nachricht erhalte, dass der Motor gestoppt hat und der bool stimmt, setze ich den bool zu false und sende die zweite Nachricht. Während dies funktioniert, dachte ich, dass es möglich sein könnte, async zu verwenden und abzuwarten? Und das könnte im Allgemeinen ein wenig effizienter sein? Oder gibt es einen anderen Ansatz, den ich besser machen könnte? Jede Rückmeldung/Anleitung wird sehr geschätzt!

+1

Nicht nah genug, um ein Duplikat genannt zu werden, aber Sie können sich das Design ansehen, das ich [für eine ähnliche Antwort] (http://stackoverflow.com/questions/36066568/asynchronChucking-Avalue) kam -without-bogging-down-a-thread/36070635 # 36070635) für eine Klasse, die Anfragen an einen SeralPort stellt und asynchron auf eine Antwort wartet. –

+0

Danke dafür, sehr nützlich! Ich werde sehen, ob ich etwas Ähnliches anpassen und implementieren kann, aber ich kann nicht die genaue Antwort verwenden, die Sie vorgeschlagen haben, da ich wirklich das Ereignis brauche, um den Empfang von Nachrichten zu handhaben. –

Antwort

0

ich Sie warten auf etwas happed und Sie keine Event-Handler zur Verfügung haben, es wäre eine gute Idee sein, async verwenden/await Muster

async Task WaitForCompletion() 
{ 
    await Task.Run(()=> 
    { 
     while(!theBoolVar) 
      Thread.Sleep(1000); 
    }); 
} 

und dann einfach in Ihrem Code verwenden

1

Meiner Meinung nach ist das Schöne an async-await nicht, dass es Ihren Anrufer anspricht, aber Ihr Code sieht einfacher aus, fast so, als ob er nicht asynchron wäre.

Sie können Ihren Anrufer auch mithilfe von Tasks und ContinueWith-Anweisungen oder mithilfe eines Backgroundworker oder anderer Methoden zum Erstellen eines Threads erreichen. Aber wenn Sie async verwenden, müssen Sie sich nicht an den Status Ihres Fortschritts erinnern, etwas, was Sie jetzt tun, indem Sie den booleschen Wert setzen.

Ihr Code würde wie folgt aussehen:

public Task InitializeAsync(...) 
{ 
    await Send1stMessageAsync(); 
    await Send2ndMessageAsync(); 
} 

In this article Eric Lippert explained async-await using a kitchen metaphor. Was passiert ist, ist, dass Ihr Thread alles tun wird, um die erste Nachricht zu senden, bis es nichts mehr tun kann, sondern auf die Antwort warten. Die Kontrolle wird dann dem ersten Anrufer gegeben, der nicht wartet. Das würden Sie hat, wenn Sie nicht erwarten, zum Beispiel, wenn Sie den folgenden Code haben:

public Task InitializeAsync(...) 
{ 
    var task1stMessage = Send1stMessageAsync(); 
    // this thread will do everything inside Send1stMessageAsync until it sees an await. 
    // it then returns control to this function until there is an await here: 
    DoSomeThingElse(); 
    // after a while you don't have anything else to do, 
    // so you wait until your first messages has been sent 
    // and the reply received: 
    await task1stMessage; 
    // control is given back to your caller who might have something 
    // useful to do until he awaits and control is given to his caller etc. 
    // when the await inside Send1stMessageAync is completed, the next statements inside 
    // Send1stMessageAsync are executed until the next await, or until the function completes. 

    var task2ndMessage = Send2ndMessageAsync(); 
    DoSomethingUseful(); 
    await task2ndMessage; 
} 

Sie schrieben, dass Sie Ereignisse benutzen, um Ihren Thread zu benachrichtigen, dass die Daten empfangen wurden. Obwohl es nicht schwierig ist, Send1stMessageAsync zu einer asynchronen Funktion zu machen, müssen Sie das Rad nicht neu erfinden. Ziehen Sie ein nugget-Paket wie SerialPortStream in Betracht, um asynchrone Funktionen zu erhalten, die Nachrichten senden und auf eine Antwort warten.

Verwandte Themen