1

我在这里遇到了一个例外:

MyException 未被用户代码处理

事实上我已经尝试过了,但是

问题是什么以及如何解决?我想要实现的是让异常被try catch包围parallel.All捕获。现在,它不知道 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

2

您在调试器中得到“未处理的用户代码”,因为您打开了“仅我的代码”设置(并且原始异常在技术上不是由您的代码处理,而是由框架的代码处理)。

关闭“只是我的代码”,您将获得不同的体验。

注意,这只是调试经验——它对常规程序流程没有任何影响。

请参阅:http: //msdn.microsoft.com/en-us/library/h5e30exc (v=vs.90).aspx

于 2013-09-12T14:33:10.813 回答
1

Parallel 成员将始终抛出 Aggregate 异常。你抓错了类型。

您需要的更改:

//catch(MyException e)
catch (AggregateException ae)
{       

   foreach (var e in ae.InnerExceptions)  // note the 's' in InnerExceptions
   {
        //do something with 'e'
   }
}
于 2013-09-12T12:19:04.030 回答
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

你也可以这样做,但你应该先阅读这个答案(来自 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 回答