2011-07-15 36 views
1

多くの研究の後、私はまだ困惑しています。私は連続的にデータを読み込んでいるシリアルポートオブジェクトを持っています。私ができることは、dataReceivedイベントを生成し、ポートと通信し、受信した値をデバッグウィンドウに出力します。だから、私はそれがすべて物理的に働いていると確信しています。問題は、シリアルポートの出力を元のスレッドに渡そうとしたときにエラーが発生することです。それは私がスレッドクロストーク(またはその効果に何か)を持つことはできないと言います。私はbackgroundWorkerを使用しようとしてきましたが、私はそれが私の頭の上に少しだけ私の初心者のスキルとプラスしたいソリューションであることを確認していない。そして、私はinvokeを使用しようとしましたが、メソッドは利用可能ではないようです。 (私は間違ったオブジェクトから呼び出すかもしれない?)とにかくセクションは以下の通りです。スレッド間のシリアルポート通信

namespace Photometer 
{ 
    class csRadiometerILT1700 
    { 
     //manufacturer specs for baud rate, databits, and stop bits 
     static string portName="COM1"; 
     static int baudRate = 1200; 
     static int dataBits = 8; 
     //instantialize a serial port object for the Radiometer 
     private SerialPort RadiometerSerial = new SerialPort(portName, baudRate, Parity.None, dataBits, StopBits.One); 


     //constructor 
     //public csRadiometerILT1700(Form ParentForm, Chart outputChart) 
     public csRadiometerILT1700() 
     { 


      //two handshaking properties of the ILT1700. Handshaking is enabled and 
      //http://stackoverflow.com/questions/6277619/problem-reading-serial-port-c-net-2-0-to-get-weighing-machine-output 
      RadiometerSerial.Handshake= Handshake.RequestToSend; 
      RadiometerSerial.DtrEnable = true; 

      RadiometerSerial.DataReceived += new SerialDataReceivedEventHandler(RadiometerSerial_DataReceived); 

     } 

     public void openPort() 
     { 
      if (!RadiometerSerial.IsOpen) 
      { 
       RadiometerSerial.Open(); 
      } 

     } 
     public void closePort() 
     { 
      RadiometerSerial.Close(); 
     } 

     string RadiometerVoltageReadingString; 
     int RadiometerVoltageReadingInt; 
     private void RadiometerSerial_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      //It's here that this.invoke()... cannot be called. 

      RadiometerVoltageReadingString= (RadiometerSerial.ReadExisting().ToString()); //y-value 
      Debug.Print(RadiometerVoltageReadingString.ToString()); 

      makeRadioReadingDouble(RadiometerVoltageReadingString); 

     } 

     private void makeRadioReadingDouble(string inputVoltageString) 
     { 

      List<double> outputVoltageDouble=new List<double>(2); 


      if (!(inputVoltageString == "\r\n" || inputVoltageString == "")) 
      { 
       string[] voltageValAndExpo = inputVoltageString.Split(new string[] { "e", "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 

       for (int inCounter = 0; inCounter < voltageValAndExpo.Count(); inCounter=inCounter+2) 
       { 
        double voltageVal = Convert.ToDouble(voltageValAndExpo[inCounter]); 
        double voltageExpo = Convert.ToDouble(voltageValAndExpo[inCounter + 1]); 

        outputVoltageDouble.Add(Math.Pow(voltageVal, voltageExpo)); 
       } 
      } 
     } 

    } 
} 

これは、すべてのIコード

  csRadiometerILT1700 Radiometer; 

      ... 

      Radiometer = new csRadiometerILT1700(); 
      Radiometer.openPort(); 

と負荷を形成する際に任意の洞察力が理解されると呼ばれます。

EDIT: 私は

public csRadiometerILT1700(Form inputForm) 
    { 

     //inputForm.Invoke(
     //two handshaking properties of the ILT1700. Handshaking is enabled and 
     //http://stackoverflow.com/questions/6277619/problem-reading-serial-port-c-net-2-0-to-get-weighing-machine-output 
     RadiometerSerial.Handshake= Handshake.RequestToSend; 
     RadiometerSerial.DtrEnable = true; 

     RadiometerSerial.DataReceived += new SerialDataReceivedEventHandler(RadiometerSerial_DataReceived); 
     inputForm.Invoke(DataReceived); 
    } 

に私のcsRadiometerILT1700コンストラクタを変更してcsRadiometerILT1700クラスの

public event Delegate DataReceived; 

を宣言します。しかし、これは私に "Datareceivedはデリゲート型でなければならない"というエラーを出します。これを今解決するにはどうしたらいいですか?正しい軌道にいるのですか?

+0

ctorから起動しないでください。イベントを設定するためのリンクは次のとおりです:http://stackoverflow.com/questions/2448487/how-to-dispatch-events-in-c/2448530#2448530 –

+0

意味のあるデータが受信されたとき、クラスはイベントを発生させる必要があります。それをEventArgs由来クラスにパックします。フォームはそのハンドラに(+ =)およびInvokesをサブスクライブします。 –

答えて

2
  1. RadiometerILT1700クラスでは、受け取った(処理された)データを報告するにはeventクラスが必要です。
  2. フォームは、そのイベントをサブスクライブします
  3. Formsイベントハンドラは、クロススレッドの問題を克服するためにthis.Invoke()を使用します。
+0

1.これはDataReceivedイベント内でトリガーされますか?シリアルデータのX量を処理したら、イベントにフラグを立てますか? 2.呼び出し元のフォームから登録するにはどうすればよいですか? 3.これは、Invoke()内に「サブスクリプション」を置くことを意味しますか? – Brad

+0

1)はい、2)他のイベントと同様に '+ ='で、3)いいえ、あなたはサブスクライブされたフォームメソッドを呼び出します。別の方法または同じ方法に。 –

+0

申し訳ありませんが、私はまだ失われています。私はもう少し手を保持する必要があります。 2)に関連する行動を説明するために、より多くの言葉を使用できますか? – Brad

0

いつでも、別のスレッドからメインスレッドに投稿しようとすると、このエラーが発生します。デリゲートを使用し、メインフォームスレッドではないスレッドから呼び出すコントロールでInvokeを呼び出す必要があります。エラーを仮定

0

は実際には:それ が作成されたスレッド以外のスレッドからアクセス

コントロールコントロール名。

問題は、別のスレッドからあなたのGUIに影響を与えることはできません。 invokeフォームまたはコントロールにコントロールを渡して変更できるようにする必要があります。あなたは他のほとんどの要素と対話することができるはずですが、フォームとは対話できません。

0

あなたがそこにthis.Invokeを呼び出すべきではありません、あなたはそれをやっている方法は、UIを代わりにあなた自身で独自のスレッドを同期しようとしているようなものです。あなたは、イベントのためにformhandle.Invoke、またはフォームクラスレジスタ内を呼び出す必要があり、その後、あなたはthis.invoke

1

Invokeを使用することができ、DelegateまたはFormまたはControlにする方法であるcsRadiometerILT1700は、これらのいずれでもないので、それはからのInvoke implemenationを継承されていませんそれらのクラス。

csRadiometerILT1700の発信者に別のイベントを発生させる必要があります。また、GUI上で別のイベントを発生させる必要があります(クロススレッドの問題もあります)。csRadiometerILT1700には、コールバックに使用できるデリゲート手巻きのイベント。

フォームにデータを格納したら、Control.InokeRequiredを使用してクロススレッド状況を検出し、Control.Invokeを使用してクロススレッドコールを行うことができます。

+0

私はデリゲートの構文について混乱していると思います。呼び出しフォームにはどのような部分が入り、イベントが処理されるクラスにはどのような部分が入りますか? – Brad

+0

'delegate'は関数シグネチャの定義です。 'Delegate'または' MultiCastDelegate'は、 'delegate'のインスタンスを表すクラスです。 'event'は、呼び出しを「呼び出す」または「呼び出す」ためのショートカットを持つ指定された' delegate'の 'MulticastDelegate'です。 – Jodrell

+0

'delegate'はどこにでも宣言でき、' event'はそれを発生させたいクラスにあるはずです。 'MulticastDelegate'イベントにマッチしてそれを購読するために使用される関数は、そのイベントを処理したいクラス上になければなりません。 – Jodrell

関連する問題