2011-12-20 15 views
0

私は新しいのでスレッドにアドバイスしたいと思います。私はオンラインでのスレッドのいくつかの記事を読んだ。Cでスレッディングを使用してCOMポートを読む#

私はcomポートのデータを読んでいます。 5秒ごとにデータを読み込んでリストボックスのデータを更新するようなスレッドを使用したいと思います。現在、すべてのデータが読み取られています。 どこから始めたらよいかわかりません。

私はスレッドコードを入れ始めますか?私はWindowsフォーム、C#VS2008を使用しています。

はここでCOMポートからデータを読み取るために私のコードです:すべての

void datareceived(object sender, SerialDataReceivedEventArgs e) 
    {    
     myDelegate d = new myDelegate(update); 
     listBox1.Invoke(d, new object[] { }); 

    } 


    public void update() 
    {   

     while (serialPortN.BytesToRead > 0) 
      bBuffer.Add((byte)serialPortN.ReadByte()); 
     ProcessBuffer(bBuffer); 

    } 

    private void ProcessBuffer(List<byte> bBuffer) 
    {    

     int numberOfBytesToRead = 125; 

     if (bBuffer.Count >= numberOfBytesToRead) 
     {    


       listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + " " + " HR: " + (bBuffer[103].ToString())); 


      // Remove the bytes read from the list 
      bBuffer.RemoveRange(0, numberOfBytesToRead); 

     } 

    }   

ありがとう!

答えて

2

なぜタイマーを使用しないのですか?このコードで

using System.Timers; 

private void InitializeComponent() 
{ 
    this.components = new System.ComponentModel.Container(); 
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
    this.Text = "Form1"; 

    Timer timer = new Timer(); 

    timer.Interval = 5000; 
    timer.Elapsed += new ElapsedEventHandler(TimerElapsed); 

    //timer.Enabled = true; // you may need this, but probably not if you are calling the start method. 
    timer.Start(); 
} 

void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    // put your code here to read the COM port 
} 

唯一の他の問題は、あなたが例外クロススレッド操作は有効ではありません取得することで、適切なフォームのInitializeComponentメソッドにそれを置きます。

あなたはこのようなあなたのコードを変更する必要があります、

private void ProcessBuffer(List<byte> bBuffer) 
{ 
    int numberOfBytesToRead = 125; 

    if (bBuffer.Count >= numberOfBytesToRead) 
    { 
     this.Invoke(new Action(() => 
     { 
      listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + " " + " HR: " + (bBuffer[103].ToString())); 
     }); 

     // Remove the bytes read from the list 
     bBuffer.RemoveRange(0, numberOfBytesToRead); 
    } 
} 

理由はProcessBuffer方法は、バックグラウンドスレッドで実行されているということです。バックグラウンドスレッドはUIスレッドのUIコンポーネントにアクセスできません。したがって、UIスレッドのリストボックスにその更新を実行するthis.Invokeを呼び出さなければなりません。

あなたはInvokeメソッドについての詳細をお知りになりたい場合はUPDATE

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

、ここで見てください:

のでTimerElapsedメソッド内で、あなたのコードを呼び出すことになるでしょうが、それはありますあなたのコードのどの部分を呼び出すべきかを私にはっきりさせないでください。 'datareceived'メソッドとは何ですか、コードスニペットでそれを呼び出すものは何もありません。

だから私はそれがバッファから来るどこので、それはProcessBufferメソッドを呼び出すことすることは意味がありません。この、

void TimerElapsed(object sender, ElapsedEventArgs e) 
{ 
    Update(); 
} 

public void Update() 
{ 
    while (serialPortN.BytesToRead > 0) 
     buffer.Add((byte)serialPortN.ReadByte()); 
    ProcessBuffer(buffer); 
} 

だろう推測していますか?

私が正しいトラックにない場合は、おそらくコードサンプルを展開してください。もっとお手伝いします。

私はあなたのコードに行ったいくつかのスタイルの変更に気をつけてください。C#のメソッドは大文字で始まり、変数bBufferを呼び出すのはC#では標準ではありません。そのメソッドがクラス内からのみ呼び出される場合は、プライベートにする必要があります。

+0

こんにちはピーター、ご返信ありがとうございます。 COMポートデータの読み込みでは、ボタンのクリックイベントの下にデータを挿入しました。私は、ボイドタイマーの下にボタンのクリックイベントハンドラを置く必要がありますか?ありがとう! – fb69

+0

私は100%フォローしていません。ボタンクリックイベントの下でデータを挿入したという意味ですか?どのデータを挿入しましたか?コードファイルのvoid TimerElapsedの後にボタンのクリックイベントハンドラを置くことができるかどうかを知りたい場合は、そうすることができます。 – peter

+0

申し訳ありませんピーター、私が意味することは、タイマの経過メソッドは、私はプロセスのバッファーコーディングを挿入することができますか?データを処理するプロセスバッファメソッド以降。 – fb69

関連する問題