アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記のようなデリゲートを利用したマルチスレッドのプログラムを組みました。
しかし、マルチスレッド内で例外がおきても、正常にプログラムが終了してしまいます。
(try-catchでも例外を捕捉できません)

マルチスレッドプログラムにおいて、例外を捕捉するにはどうすれば、いいのでしょうか?

using System;
using System.Threading;
class Class1
{
delegate void delg();

public static void Main()
{
delg d = new delg(multi);
d.BeginInvoke(new AsyncCallback(call), null); //マルチスレッド開始

System.Threading.Thread.Sleep(500);
//マルチスレッドで例外を強制的に投げているので、
//ここまでたどり着く前にアプリケーションが落ちるはず。
//しかし、実際には正常終了。
Console.WriteLine("メインメソッド 正常終了");
}

public static void multi()
{
Console.WriteLine("マルチスレッドで実行中");
throw new Exception();//例外を強制的に投げる。
}

public static void call(IAsyncResult ar)
{
Console.WriteLine("コールバックメソッド実行");
}
}

A 回答 (3件)

>#1の方


BeginInvokeは「非同期」の実行ですので、マルチスレッドになります。

で、非同期delegateでのマルチスレッドですが、どうも特殊みたいで、BeginInvoke中での例外を別スレッドでは受けられないようで、該当スレッド中で例外を受ける必要があるようです。
http://blog.livedoor.jp/gushwell/archives/238323 …

Threadクラス使えばこのような方法で問題無いみたいですが、当然引数、戻り値は使えませんから、例えばこんな手を使います。
http://www.atmarkit.co.jp/fdotnet/mthread/mthrea …

参考URL:http://blog.livedoor.jp/gushwell/archives/238323 …
    • good
    • 0
この回答へのお礼

回答どうもありがとうございます。
紹介して頂いたブログを参考に問題が解決しました。

ここからは、ただの疑問点(困ってはいません)なのですが、
紹介して頂いたブログによると、コールバックメソッドの方からControlフォームに向けて、非同期デリゲートで例外を新規に投げるといったものですよね。
このようにした場合、Controlフォームのどこにtry-catchを入れればいいのでしょうか?
もしかしたらトンチンカンな質問かもしれませんが、気が向いたら回答頂ければ助かります。

お礼日時:2005/09/20 00:39

>このようにした場合、Controlフォームのどこにtry-catchを入れればいいのでしょうか?



推測ですが、try catchでは受け取れないと思います。

多分、こういう手を使うのでは。
http://www.atmarkit.co.jp/fdotnet/dotnettips/320 …

参考URL:http://www.atmarkit.co.jp/fdotnet/dotnettips/320 …
    • good
    • 1
この回答へのお礼

度重なる回答本当にどうもありがとうございます。

お礼日時:2005/09/20 02:07

とりあえずマルチスレッドの複数のスレッドというのが起こされたようには見えませんが。

。。

単に、デリゲートのBeginInvokeメソッドを使って
multiを呼び出しただけのように見えますが。。。

以下のコードのようなことをやりたいでしょうか?
using System;
using System.Threading;
class Class1 {
public static void Main() {
(new Thread(new ThreadStart(multi))).Start();
}

public static void multi() {
Console.WriteLine("マルチスレッドで実行中");
try{
throw new Exception();
}
catch{
Console.WriteLine("マルチスレッド実行中例外があがりました。");
}
}
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
質問のプログラム例で、マルチスレッドになっているはずです。
(MainメソッドのThread.Sleep(500)を削除するとうまく動かないはずです)
http://www.atmarkit.co.jp/fdotnet/mthread/mthrea …

また、戻り値や引数を渡したいため、Threadクラスではなく、デリゲートを使いました。
もちろん、戻り値・引数が使えるのであれば、別にデリゲートにこだわりません。
(例示したプログラムは簡単化のために、あえて引数・戻り値のないvoid型としました)

お礼日時:2005/09/19 02:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています