- PR -

デリゲート内で発生した例外を取得するには?

1
投稿者投稿内容
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2004-11-02 15:33
こんにちは。

デリゲート内で例外が発生した場合にそれをキャッチするには、
どのようにすればよろしいでしょうか。

デリゲートの実行を Try Catch でくくってみましたが、
当然スルーされました。

デリゲートに登録するメソッドの中身を Try Catch でくくったところ、
キャッチはできましたが、アプリケーションがとまってしまいました。
(C#Builderでデバッグ実行しています。)

デリゲートのシグネチャに戻り値を指定、または、out引数を使用して判定するのが
一般的なのでしょうか。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-11-02 16:07
引用:

masaさんの書き込み (2004-11-02 15:33) より:
デリゲート内で例外が発生した場合にそれをキャッチするには、
どのようにすればよろしいでしょうか。

デリゲートの実行を Try Catch でくくってみましたが、
当然スルーされました。


どんなプログラムですか?
デリゲートの呼び出しはどう記述してます?

基本的にはデリゲートは、あたかもそのままメソッドを呼び出したかのように動きますので、例外処理なんかも変わりなくできます。

ひょっとしてイベントがらみですか?

# ちなみに「【当然】スルーされました。」と思ったのはなんででしょう?
# いや、なんとなくならいいです、単なるちょっとした興味です。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-11-02 16:56
コード:
private void button1_Click(object sender, System.EventArgs e)
{
    EventHandler d;
    d=new EventHandler(F);

    try
    {
        d(null,null);
    }
    catch(Exception ex) 
    {
        MessageBox.Show(ex.Message);
    }
}

private void F(object sender, System.EventArgs e)
{
    throw new Exception("F()内の例外");
}


このようなコードを書きましたが、メッセージボックスが表示されました。
もちろんメッセージは「F()内の例外」です。

どういうことでしょうね。
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2004-11-02 17:03

> どんなプログラムですか?
> デリゲートの呼び出しはどう記述してます?

お察しのとおり、コントロールのイベントがらみです。

今、リスナーのようなものを作っています。
制御対象のコントロールで発生したイベントをラップして返すようなクラスです。

で、もともとのイベントデータに対して何らかの判断(許可/不許可など)を行う際、
その判断の部分をデリゲートを使って遅延バインドさせようと考えています。
基本的には「例外は発生しないもの、発生しても不許可」のようなルールで行く予定ではあります。


> 当然スルー

MSDEなどでデリゲートの項目を見ると、
・内部で例外が発生した場合はデリゲート呼出にもどる。
・マルチキャストの場合は以降のメソッドは実行されない。

というような説明がありましたので、
デリゲートというのはこういうものなのかなと思った上での発言でした。

masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2004-11-02 17:11
呼び出し方は、

if ( m_Delegate != null ) {
 m_Delegate(param1, param2)
}

とか

if ( m_Delegate != null ) {
 bool ret = m_Delegate(param1, param2)
}

とかマルチキャストで、戻り値をみながらひとつ成功するまで、という場合は、

foreach ( System.Deledate methods in m_Deledate.GetInvocationList() ) {
 // System.Deledate は実際には m_Deledate が受け取るシグネチャです

 if ( methods != null ) {
  bool ret = d(param1, param2);
  if ( ret ) {
   break;
  }
 }
}

のようなこともしています。

masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2004-11-02 17:26

ごめんなさい。お騒がせしました。

該当のデリゲートをもう一箇所呼び出していました。
Try Catch を掛けたのは、その2箇所のうちの後ろの処理でした。
1つめにTry Catch を掛けたところ、トラップされました。
ただ、メッセージボックスを出すようにすると、フリーズしかけるのは変わらないんです。。
1日コーディングしていると2〜3回 C#Builder が落ちてしまう環境なので、なんともいえないのですが・・・TT。

そうなんですよね、例外が無視されるのもおかしいなあとは思っていたんです。
コントロールのイベントハンドラ内では普通に例外が発生するんですから。
「どこかでフックしてくれているのかなあ」とか勘ぐりすぎました。

1

スキルアップ/キャリアアップ(JOB@IT)