0

ac#アプリケーションでGSMモデムからのメッセージを読みたい。次のコードを記述し、別のスレッドにThread.sleep()を実装するためにバックグラウンドワーカーを使用しました。しかし、port.ReadExisting()を使用する時点では、ポートから何も読み取られていません。バックグラウンドワーカーを処理する間違った方法を使用していますか?

    private void btn_Read_Click(object sender, EventArgs e)
    {
        lvwMessages.Items.Clear();
        status_other.Visible = true;
        status_other.Text = "Loading messages...";
        if (read_all.Checked)
        {
            port.WriteLine("AT+CMGL=\"ALL\"");

        }
        else if (read_unread.Checked)
        {
            port.WriteLine("AT+CMGL=\"REC UNREAD\"");
        }
        port.DiscardOutBuffer();
        port.DiscardInBuffer();

        backgroundWorker1.RunWorkerAsync();
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(5000);
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
     string res = port.ReadExisting();// here no data is fetched into res
        //rest of the code
4

2 に答える 2

2

実際、もしそうなら、あなたはそれを間違っているportのです。には非同期のSerialPortイベントがあり、データが着信すると自動的に呼び出されます。これにより、応答を段階的に作成し、完全な応答を受信したときにコードで検出できます。SerialPortDataReceived

5秒間待つだけでは、完全な返信を受け取ることはできません。

例:

private String m_receivedData = String.Empty;

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    m_receivedData += (sender as SerialPort).ReadExisting();

    if (<check whether m_receivedData contains everything I need> == true)
    {
        ProcessData(m_receivedData);
        m_receivedData = String.Empty;
    }
}

port_DataReceivedこれは別のスレッドで呼び出されるためInvoke、GUIを更新する場合はを使用する必要があることに注意してください。

編集
明確にするために:ABackgroundWorkerは、バックグラウンドで操作を実行したり、ステータスを報告したり、完了したときに報告したりするために使用する必要があります。特に、実際のプロセスに「データが存在するまで待機する」メカニズムが含まれている場合は、これを使用して一時停止するだけでは役に立ちません。これは、上記のイベントです。

于 2012-07-20T11:10:13.197 に答える
1

はい、バックグラウンドワーカーを間違った方法
で使用すると、SerialPortの直接データ受信イベントを使用する方が適切です。または、時間ベースのソリューションを使用する場合は、ワンショットタイマーの方が適切です。

于 2012-07-20T11:09:45.633 に答える