2017-08-08 89 views
1

我有一個程序化的GUI方法需要多次從串行中檢索數據。在VB中讀取串行數據時發生非阻塞等待

它每次都這樣做,它需要等待串行數據功能完成(例如,通過平均從串行接收到的所有數據,該功能可以工作15秒)。

什麼是一些非阻塞的方式等待呢? 起初我試過Threading.Thread.Sleep(15000),但是這完全鎖定了程序。

我也試過非常相似的方法(仍然使用睡眠,但以較小的間隔)。阻擋仍然存在,只有0.5秒的時間間隔。

Public Sub ResponsiveSleep(ByRef iMilliSeconds As Integer) 
    Dim i As Integer, iHalfSeconds As Integer = iMilliSeconds/500 
    For i = 1 To iHalfSeconds 
     Threading.Thread.Sleep(500) : Application.DoEvents() 
    Next i 
End Sub 

在我調用wait函數之前,我應該使串行讀函數成爲一個單獨的線程嗎?

+0

線程是不好的做法如今,也許你可以考慮異步功能和'Tasks' – Jaxi

+0

但是,是的,你要我實際使用DataReceived事件檢索始終保持你的工作和你的GUI單獨如果可能的話:) – Jaxi

回答

1

一般來說,I/O和任何其他阻塞調用應放在一個單獨的線程。您可能會得到如下結果:

Public Async Sub MyUserInterfaceEventThatMakesTheAsyncCallWork() 
    Dim result as String = Await ResponsiveSleep() 
    MyUserInterface.Text = result 
End Sub 

Public Async Function ResponsiveSleep() As Task(Of String) 
    Await Task.Delay(10000) 'however long you want the delay to be, or delay logic here 
    'Calls here should always be Await, or they'll be synchronous 
    Return "the result of my thing!" 
End Function 

這很有用,因爲您不必過多考慮它。只要你在另一個函數中是異步的,你可以或多或少地寫它,就好像它是同步的。

2

如果在沒有輪詢的情況下收到數據,則可能會實施DataReceived事件。 更多的信息https://msdn.microsoft.com/it-it/library/system.io.ports.serialport.datareceived(v=vs.110).aspx

+0

。但是,如何在沒有Thread.Sleep鎖定的情況下讓它運行(即使在我的ResponsiveSleep函數中)。 – 22332112

+0

我不確定我是否理解。只要內部輸入緩衝區大於ReceivedBytesThreshold屬性,就會觸發該事件。默認值爲1. 將其設置爲預期的字節數,然後處理它們。 –