2017-08-08 5 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 

私は待機関数を呼び出す前にシリアル読み取り関数を別のスレッドにする必要がありますか?

+0

スレッドは現時点では悪い習慣ですが、おそらく非同期関数と 'Tasks'を調べることができます。 – Jaxi

+0

しかし、可能であれば、作業と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

私は実際にDataReceivedイベントを使用しています。しかし、どうすればThread.Sleep(私のResponsiveSleep関数でさえ)をロックしなくてもそれを実行させることができます。 – 22332112

+0

私は分かりません。このイベントは、内部入力バッファがReceivedBytesThresholdプロパティより大きい場合に起動されます。既定値は1です。 予想されるバイト数に設定し、処理します。 –

関連する問題