残念ながら、C# でシリアル ポートのデータを待つのはトリッキーpoll()
です。
SerialPort.DataReceived
着信データに対して呼び出される関数を受け取るものがあります。したがって、任意のイベントをトリガーする関数をそこに割り当てます。別の関数 (実際に待機する関数) は、このイベントを待機する必要があります。
以下は簡単な例で、コメントが付けられていますが、要するに: はTestFunc
シリアル ポートを初期化して開きます(特に を割り当てますDataReceived
)。はProxy()
、データが到着するたびに呼び出される関数で、イベントをトリガーします。WaitForAData()
実際、データが表示されたときにトリガーされるイベントを待ちますProxy()
。lock(){}
の関数を囲むMonitor
s がないと、正しく動作しないことに注意してください。
WaitForAData()
これは単なる例です。おそらく、タイムアウトの場合に例外をトリガーするように関数を作り直す必要があるでしょう。また、待機を開始する前にトリガーされた場合に備えてブール変数を追加するにはProxy()
、シリアルポートに既にデータがあります。しかし、私はそれをテストしました(私は今そのような機能が必要です☺)、そしてそれは動作します.
namespace MyNamespace
{
class MySerial
{
///A condition variable that signals when serial has a data
private System.Object SerialIncoming;
public MySerial()
{
SerialIncoming = new Object();
}
/**
* A proxy function that will be called every time a data arrived
*/
private void Proxy(Object unused1, SerialDataReceivedEventArgs unused2)
{
Console.WriteLine("Data arrived!");
lock (SerialIncoming)
{
Monitor.Pulse(SerialIncoming);
}
}
/**
* Waits for a data for the time interval Timeout
* \param Timeout a timeout in milliseconds to wait for a data
* \returns true in if a data did arrived, and false else
*/
public bool WaitForAData(int Timeout)
{
lock (SerialIncoming)//waits N seconds for a condition variable
{
if (!Monitor.Wait(SerialIncoming, Timeout))
{//if timeout
Console.WriteLine("Time out");
return false;
}
return true;
}
}
/* Just a test function: opens a serial with speed, and waits
* for a data for the «Timeout» milliseconds.
*/
public void TestFunc(string serial, int speed, int Timeout)
{
SerialPort ser = new SerialPort(serial);
ser.BaudRate = speed;
ser.DataReceived += Proxy;
ser.Open();
if (WaitForAData(Timeout))
Console.WriteLine("Okay in TestFunc");
else
Console.WriteLine("Time out in TestFunc");
}
}
}
更新:問題は私の 1 日の ½ を無駄にしたので、誰かの時間を節約できることを願っています: 上記のコードはモノラルでは機能しません (ただし、MS 実装では機能します)。