1

ここで例外があります:

MyException はユーザー コードによって処理されませんでした

実際にやってみましたが、

問題とその解決方法は何ですか? 私が達成したいのは、parallel.All で囲まれた try catch によってキャッチされる例外を取得することです。現在、それは try catch を認識せず、例外がユーザー コードによって処理されないことを通知します。TestParallel1これは私が持っているプログラムの簡略化された形式であるため、例外をスローするメソッドが必要であることに注意してください。例外が発生した場合、他のすべてのスレッドをすぐに停止したいと考えています。さらに、例外が並列の外に伝播することを望みます。

namespace WindowsFormsApplication1
{
    static class Program
    {

        public static void Main()
        {
            try
            {
                List<Action> act = new List<Action>
                      {
                         ()=>TestParallel1(),
                         () => TestParallel1()
                      };

                Parallel.Invoke(act.ToArray());
            }
            catch (AggregateException ae)
            {
                foreach (var e in ae.InnerExceptions)  // note the 's' in InnerExceptions
                {
                    //do something with 'e'
                }
                //do something
            }
        }

        public class MyException : Exception
        {
        }

        public static void TestParallel1()
        {
            throw new MyException();
        }
    }
}

ここに画像の説明を入力

4

3 に答える 3

0

この例外をキャッチして Parallel を使用するには、次のようにします。

        List<Action> act = new List<Action> { () => TestParallel1(), 
                                              () => TestParallel1() };

        Parallel.ForEach(act, a =>{
            try
            {
                a.Invoke();
            }
            catch (MyException ae)
            {
                //do something
            }
        });

編集

イベントとデリゲートが問題ない場合、このようなことがうまくいくかもしれませんが、
このコードのほうが見栄えが良いことは承知していますが、アイデアが表示されるので、お役に立てば幸いです:)

public partial class MainWindow : Window
{
    List<MyThread> threads = new List<MyThread>();

    public MainWindow()
    {
        var thread1 = new MyThread();
        thread1.A = () => TestParallel1();
        thread1.RaisError += RaisError;

        var thread2 = new MyThread();
        thread2.A = () => TestParallel1();


        threads.Add(thread1);
        threads.Add(thread2);

        Parallel.ForEach(threads, t => { t.Start(); });
    }

    public void RaisError()
    {
        Parallel.ForEach(threads, t => { t.Stop(); });
    }

    public static void TestParallel1()
    {
        throw new MyException();
    }
}

public class MyException:Exception{}


public class MyThread
{
    public Action A { get; set; }
    public delegate void Raiser();
    public event Raiser RaisError;

    public void Start()
    {
        try
        {
            A.Invoke();
        }
        catch (MyException me)
        {
            RaisError();
        }
    }

    public void Stop()
    {
        // do some stop
    }
}

編集 2

これを行うこともできますが、最初にThis Answer (Scott Chamberlain から)を読む必要があります。

        List<Action> act = new List<Action> { () => TestParallel1(), 
                                          () => TestParallel1() };

        Parallel.ForEach(act, (a, state) =>
        {
            try
            {
                a.Invoke();
            }
            catch (MyException ae)
            {
                state.Stop();
            }
        });
于 2013-09-12T13:08:03.007 に答える