C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.29443 の関連記事表示

<< 0 >>
■29443  UDP非同期通信について
□投稿者/ フミ -(2008/12/09(Tue) 20:24:24)

    分類:[C#] 

    毎度お世話になります。
    フミと申します。

    C#にてUDPによる非同期通信を行っています。
    通信をやめるためにUdpClientを閉じたところ、
    コールバック内で例外が発生してしまい困っています。

    ウィンドウズのフォームにボタンが2つあり、
    ボタン1を押すとUDPの受信待ち(udpclient.BeginReceive)、
    ボタン2を押すとUDPのソケットをクローズ(udpclient.Close)します。

    受信はうまくいくのですが、
    受信が終わって、ボタン2を押しクローズしようとすると、
    非同期受信のコールバック内でエラーが発生します。

    エラー内容は

        「破棄されたオブジェクトにアクセスできません。
         オブジェクト名 'System.Net.Sockets.UdpClient' です。」

    と表示されます。

    コールバックで使うのに先にクローズでUdpClientが破棄されてしまうためだと思われるのですが、
    何かプログラムに誤りあるいは対処法ありますでしょうか??


    以下、用いたプログラムです。

    //WindowsForm
    public partial class Form1 : Form
    {
    //UDP Client
    UdpStateClass usc;

    //受信データ
    byte[] receiveData;

    //コンストラクタ
    public Form1()
    {
    InitializeComponent();
    }

    //ボタン1クリック イベント
    private void button1_Click(object sender, EventArgs e)
    {
    //UDPStateクラスのインスタンス
    usc = new UdpStateClass();

    //エンドポイントとUDPクライアントを入れます
    usc.endPnt = new IPEndPoint(IPAddress.Any, 44444);
    usc.udpClt = new UdpClient(44444);

    //UDPの非同期受信開始 コールバックはreceiveCallback
    usc.udpClt.BeginReceive(new AsyncCallback(receiveCallback), usc);
    }

    //ボタン2クリック イベント
    private void button2_Click(object sender, EventArgs e)
    {
    //ソケットを閉じる
    usc.udpClt.Close();
    }

    //コールバック
    public void receiveCallback(IAsyncResult ar)
    {
    //IAsysncResultからUDPClientとIPEndPointを受け取る
    UdpClient uc = ((UdpStateClass)(ar.AsyncState)).udpClt;
    IPEndPoint iep = ((UdpStateClass)(ar.AsyncState)).endPnt;

    //受信データを配列に格納
    receiveData = uc.EndReceive(ar, ref iep);
    /* ↑ボタン2を押しcloseすると上の行でエラー発生
    * 「破棄されたオブジェクトにアクセスできません。
    *  オブジェクト名 'System.Net.Sockets.UdpClient' です。」
    */
    }
    }

    //UDPStateクラス
    public class UdpStateClass
    {
    public IPEndPoint endPnt;
    public UdpClient udpClt;
    }
親記事 /過去ログ53より / 関連記事表示
削除チェック/

■29468  Re[1]: UDP非同期通信について
□投稿者/ .SHO -(2008/12/10(Wed) 10:37:03)
    No29443 (フミ さん) に返信

    UDPなのでClose処理の最中にコールバックがポストされちゃうのかも知れないですね。
    コールバックの処理を try で囲ってしまってはどうでしょう?
記事No.29443 のレス /過去ログ53より / 関連記事表示
削除チェック/

■29594  Re[2]: UDP非同期通信について
□投稿者/ フミ -(2008/12/11(Thu) 11:49:30)
    No29468 (.SHO さん) に返信

    返信ありがとうございます!
    コールバック内をtry-catchで囲むとエラーはでなくなりました。

    しかし、例外があったまま握りつぶしているような気がするので、
    もっと根本的な解決をした方が堅牢になるのでしょうね。。。

    とりあえず、お教えいただいた通り、このままtry-catchを使ってみます。
    よりよい方法も探してみます。
記事No.29443 のレス /過去ログ53より / 関連記事表示
削除チェック/

■29597  Re[3]: UDP非同期通信について
□投稿者/ .SHO -(2008/12/11(Thu) 12:19:19)
    No29594 (フミ さん) に返信

    > しかし、例外があったまま握りつぶしているような気がするので、
    > もっと根本的な解決をした方が堅牢になるのでしょうね。。。

    えっと、そのままではダメです。
    私が言いたかったのは Close した後での例外なので
    所詮は捨ててしまっても問題ないということです。

    従って、確実に対処するには

    usc.udpClt.Close();

    の前で、フラグを立て try の中でフラグチェックをしてClose処理の
    時だけスルーするのが堅牢(?)なシステムです。
記事No.29443 のレス /過去ログ53より / 関連記事表示
削除チェック/

■29890  Re[4]: UDP非同期通信について
□投稿者/ フミ -(2008/12/16(Tue) 12:14:19)
    2008/12/16(Tue) 12:16:25 編集(投稿者)

    No29597 (.SHO さん) に返信

    返信ありがとうございます!

    Flag = true;
    usc.udpClt.Close();



    //コールバック
    public void receiveCallback(IAsyncResult ar)
    {
    try{
    if(!Flag)
            {
    //処理
    }
    }
    catch
    {
    //何もしない
    }
    }

    でしょうか?
    ひとまずこれでやってみます。
記事No.29443 のレス /過去ログ53より / 関連記事表示
削除チェック/

■29891  Re[5]: UDP非同期通信について
□投稿者/ .SHO -(2008/12/16(Tue) 12:21:49)
    No29890 (フミ さん) に返信

    > でしょうか?

    ごめんなさい。表現が正確じゃなかったです。
    フラグチェックするのは、try の中じゃなくて catch の中です。

    try の中の処理そのものを フラグで囲ってしまうのなら
    try はいらないですね。

    その方法でもいいかも?
    どっちでもいいです。
記事No.29443 のレス /過去ログ53より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -