2016-05-16 60 views
0

我正在寫一個程序,與我設計的一些控制硬件進行通信。硬件驅動電機,我試圖做的第一件事就是初始化電機。 硬件是通信控制的,所以要做任何事情,我只需通過USB發送一條消息到硬件。 要初始化電機,我必須發送2條消息;在我發送第一個信號後,它將電機向傳感器移動,當它發出信號時它會停下來,並向我發送一條信息,告訴我它已經停止,此時我會發送另一條信息,告訴它驅動電機進入相反的方向非常緩慢,直到它從傳感器出來。使用異步/等待或別的東西

我所有的通信接待是在SerialPortDataReceived事件。我可以等待相關消息併發送第二條消息的最佳方式是什麼?此刻,我只是簡單地使用了一個剛剛在初始化之前設置爲true的bool類型的屬性,然後在我的事件處理程序中,如果我收到告訴我電機已停止且bool爲真的消息,則將bool爲虛假併發送第二條消息。雖然這工作,我認爲它可能會使用異步和等待?而且這總體上可能更有效一些?還是有另一種方法可以讓我做得更好? 任何反饋/指導將不勝感激!

+1

不夠近似被稱爲重複,但你可能想看看我想出來的設計[對於類似的答案](http://stackoverflow.com/questions/36066568/asynchronously-checking-a-value -with-bogging-down-a-thread/36070635#36070635)將隊列請求排隊到SeralPort並等待異步響應的類。 –

+0

謝謝你,非常有用!我會看看我是否能夠適應和實施類似的東西,但我不能使用你提出的確切答案,因爲我確實需要處理消息接收事件。 –

回答

0

我你在等待的東西發梗和你沒有事件處理程序在您的處置它是使用一個好主意異步/ AWAIT模式

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

,然後就在你的代碼中使用

await WaitForCompletion(); 
1

在我看來,異步等待的好處並不在於它使得調用者響應,但是你的代碼看起來更容易,就好像它不是異步等待一樣。

保持調用者響應也可以使用Tasks和ContinueWith語句或使用Backgroundworker或其他方法創建線程來完成。但是,如果您使用異步等待,則不必記住進度的狀態,您現在可以通過設置布爾值來記住。

您的代碼應該是這樣的:

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

In this article Eric Lippert explained async-await using a kitchen metaphor。發生什麼事是你的線程會做所有事情來發送第一條消息,直到它不能再做任何事情,但等待答覆。然後控制權給不等待的第一個呼叫者。那將是你,如果你不等待,例如,如果你有下面的代碼:

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; 
} 

你寫你自己使用事件來通知您的線索,該數據已經收到。儘管將Send1stMessageAsync設置爲異步函數並不困難,但您不必重新發明輪子。考慮使用像SerialPortStream這樣的nuget包來獲取發送消息並等待回覆的異步函數。