1

さて、私のコードには、以前は表示されなかったこの突然の問題があります。

  public void StartUdpListener(Object state)
    {


       /* sock1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        sock1.Bind(receiveEndPoint);

        EndPoint ep = (EndPoint)receiveEndPoint;*/



       recv = sock1.ReceiveFrom(receivedNotification, ref ep);

       notificationReceived = Encoding.ASCII.GetString(receivedNotification, 0, recv);

       //sock1.Close();

       if (listBox1.InvokeRequired)
       {
           this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });
       }
       listBox.AppendLine(notificationReceived);


       if (listBox1.InvokeRequired)
       {
           pos = listBox1.FindString(notificationReceived);
           if (pos >= 0)
           {
           }
           else
           {
               this.Invoke((MethodInvoker)delegate { this.listBox1.Items.Add(listBox.ToString()); });
           }
       }

    }

次の行を示すObjectDisposedExceptionが発生します。

   this.Invoke((MethodInvoker)delegate { listBox = new StringBuilder(this.listBox1.Text); });

listBox1が破棄されているため、実行できません。それはどのように可能であり、実行する必要があることはありますか?

4

2 に答える 2

1

私は次の仮定をしています:

  1. このコードは、フォーム (System.Windows.Forms.Form) のメソッドです。
  2. 変数「listBox1」は、フォーム上の ListBox コントロールです。
  3. フォームが閉じられたときに ObjectDisposedException を受け取っています。
  4. このメソッドを別のスレッドで実行しています (コードには示されていませんが、質問によって暗示されています)。

フォームが閉じられたときに、ソケットの receiveFrom() 呼び出しでコードがブロックされていると思います。ネットワークから次のメッセージが到着すると receiveFrom が返され、その後、受信したメッセージを存在しないリストボックスに入れます。このリストボックスに初めてアクセスするのは、StringBuilder を作成するときのコード行「this.listBox1.Text」です。これは、ObjectDisposeException を発生させる行です。listBox は破棄される可能性が高いオブジェクトですが、メッセージの受信速度によっては、この時点で Form になることもあります。

やらなければならないことはたくさんあるようですが、何が適切なアドバイスなのかわかりません。最初に上記の仮定 1 ~ 4 を検証してから、複数のスレッドを使用しないようにアプリケーションをリファクタリングすることを検討します。私がこの提案を行うのは、これがアプリケーションで発生する可能性がある唯一の「スレッド化」の問題ではないと想定しなければならないからです。その仮定は確かに間違っているかもしれません。その場合、答えは無視してかまいません。

あなたの質問の「何をする必要があるか」の部分をより限られた範囲に制限する場合、ウィンドウを閉じる前にUDPレシーバーを適切にシャットダウンすることをお勧めします。

于 2009-10-29T11:53:07.283 に答える
-1

このブロックに関するコメント:

if (listBox1.InvokeRequired)
{
    this.Invoke((MethodInvoker)delegate { listBox = new
        StringBuilder(this.listBox1.Text); });
}
listBox.AppendLine(notificationReceived);

StringBuilder (リストボックス) は、.AppendLine を実行した時点で null である可能性があります。これは、リストボックスを使用しているスレッドとは別のスレッドで作成しているためです。また、新しい StringBuilder オブジェクトは、このコードが非 UI スレッド (listBox1.InvokeRequired) でチェックされている場合にのみ作成されます。

于 2009-05-21T12:53:03.623 に答える