none
シリアルポートの再接続でやらなければならないことはありますか? RRS feed

  • 質問

  • C#でRS-232Cによるシリアル通信プログラムを作成しているのですが、
    一度シリアル通信の接続をしてから、一旦通信を切断して再接続を行おうとすると
    必ずUnauthorizedAccessExceptionが出ます。
    しかもポートへのアクセスが拒否されているはずなのに接続されています。

    切断は以下のソースでやっています。

    serialPort1.DtrEnable = false;
    serialPort1.RtsEnable = false;
    serialPort1.Close();
    serialPort1.Dispose();

    これら以外に必要な処理はあるのでしょうか?

    ちなみにやりたいことは以下の2点です。
    ・同ソフトでシリアル通信の再接続を行えること。
    ・別のターミナルソフト(TeraTerm等)で接続している状態で同ソフトで接続を行い、
    一度エラーになってから別のターミナルソフトを切断し、再度同ソフトで接続したときにエラーなく接続が行えること。

    よろしくお願い致します。
    2010年1月7日 3:21

回答

  • 以下のコードのみでテストしても再接続できませんか?
    他でポートが使用中でエラーになった後に再接続をさせてます。

    原因は他のアプリで切断したつもりが実際には切断できてないとか・・・

    #Disposeしてるのが原因かと思ったけどDisposedExceptionは吐かないのね

    System.IO.Ports.SerialPort otherAppPort; //別の通信ソフトの代わり
    System.IO.Ports.SerialPort port;
    
    //フォームにシリアルポートを追加したならここら辺は自動で作成されている
    otherAppPort = new System.IO.Ports.SerialPort("COM1");
    port = new System.IO.Ports.SerialPort("COM1");
    
    try
    {
        //別の通信ソフトがポートを開いているのと同様の状態にする。
        otherAppPort.Open();
    }
    catch (UnauthorizedAccessException)
    {
        System.Diagnostics.Debug.WriteLine("COM1が他のアプリで使用中");
        return;
    }
    
    try
    {
        port.Open();
    }
    catch (UnauthorizedAccessException)
    {
        System.Diagnostics.Debug.WriteLine("COM1がotherAppPortで使用中だから正常");
    }
    
    /* 開いていないのだからやる意味のない操作
    port.DtrEnable = false;
    port.RtsEnable = false;
    port.Close();
    */
    
    otherAppPort.Close();
    
    port.Open();
    System.Diagnostics.Debug.WriteLine("port1は閉じてるからport2が開ける");
    port.DtrEnable = false;
    port.RtsEnable = false;
    port.Close();
    port.Dispose();
    
    port.Open(); //port2をDisposeしたのに使用してる。エラーにはならないけどやったらダメ。
    port.Close();
    port.Dispose();
    
    //新しいインスタンスを作り直す。
    port = new System.IO.Ports.SerialPort("COM1");
    port.Open();
    port.Close();
    port.Dispose();
    
    otherAppPort.Dispose();

    >新しくSerialPort型の変数を作成するということでしょうか?

    変数を作成するのではなくインスタンスと作成します。変数に格納される実体を作成すると考えればいいです。
    上のコードでnewがくっついているところでインスタンスが作成してます。

    • 回答としてマーク keel_law 2010年1月12日 7:55
    2010年1月7日 12:30

すべての返信

  • serialPort1.Dispose();を消しましょう。

    DisposeされたSerialPortを再利用は駄目です。
    DisposeするならSerialPortのインスタンスを新たにNewしましょう。
    • 回答としてマーク keel_law 2010年1月7日 8:30
    • 回答としてマークされていない keel_law 2010年1月7日 8:31
    • 回答としてマーク keel_law 2010年1月7日 8:31
    • 回答としてマークされていない keel_law 2010年1月7日 8:35
    2010年1月7日 3:44
  • ご回答ありがとうございます。
    早速試してみます。
    2010年1月7日 8:30
  • Disposeを消しただけでは駄目なようです。

    >DisposeするならSerialPortのインスタンスを新たにNewしましょう。
    オブジェクト指向型言語は初心者のためこの意味がよくわかりません。
    新しくSerialPort型の変数を作成するということでしょうか?
    2010年1月7日 9:54
  • Disposeを消しただけでは駄目なようです。

    >DisposeするならSerialPortのインスタンスを新たにNewしましょう。
    オブジェクト指向型言語は初心者のためこの意味がよくわかりません。
    新しくSerialPort型の変数を作成するということでしょうか?
    2010年1月7日 9:55
  • 以下のコードのみでテストしても再接続できませんか?
    他でポートが使用中でエラーになった後に再接続をさせてます。

    原因は他のアプリで切断したつもりが実際には切断できてないとか・・・

    #Disposeしてるのが原因かと思ったけどDisposedExceptionは吐かないのね

    System.IO.Ports.SerialPort otherAppPort; //別の通信ソフトの代わり
    System.IO.Ports.SerialPort port;
    
    //フォームにシリアルポートを追加したならここら辺は自動で作成されている
    otherAppPort = new System.IO.Ports.SerialPort("COM1");
    port = new System.IO.Ports.SerialPort("COM1");
    
    try
    {
        //別の通信ソフトがポートを開いているのと同様の状態にする。
        otherAppPort.Open();
    }
    catch (UnauthorizedAccessException)
    {
        System.Diagnostics.Debug.WriteLine("COM1が他のアプリで使用中");
        return;
    }
    
    try
    {
        port.Open();
    }
    catch (UnauthorizedAccessException)
    {
        System.Diagnostics.Debug.WriteLine("COM1がotherAppPortで使用中だから正常");
    }
    
    /* 開いていないのだからやる意味のない操作
    port.DtrEnable = false;
    port.RtsEnable = false;
    port.Close();
    */
    
    otherAppPort.Close();
    
    port.Open();
    System.Diagnostics.Debug.WriteLine("port1は閉じてるからport2が開ける");
    port.DtrEnable = false;
    port.RtsEnable = false;
    port.Close();
    port.Dispose();
    
    port.Open(); //port2をDisposeしたのに使用してる。エラーにはならないけどやったらダメ。
    port.Close();
    port.Dispose();
    
    //新しいインスタンスを作り直す。
    port = new System.IO.Ports.SerialPort("COM1");
    port.Open();
    port.Close();
    port.Dispose();
    
    otherAppPort.Dispose();

    >新しくSerialPort型の変数を作成するということでしょうか?

    変数を作成するのではなくインスタンスと作成します。変数に格納される実体を作成すると考えればいいです。
    上のコードでnewがくっついているところでインスタンスが作成してます。

    • 回答としてマーク keel_law 2010年1月12日 7:55
    2010年1月7日 12:30
  • 回答ありがとうございます。
    返信遅くなってすみません。

    上記の方法で試して見たところできました。
    今まではインスタンスを作成せずにクラスに直接(?)設定を行っていました。

    そのために出来なかったようです。

    newの意味がやっとわかりました^_^;
    丁寧な回答ありがとうございます。

    2010年1月12日 7:55