日期:2014-05-17  浏览次数:20992 次

多线程异常问题
static void Main(string[] args)
  {
  Console.WriteLine("Main Thread:" + Thread.CurrentThread.ManagedThreadId);
  Action action = Method;
  try
  {
  IAsyncResult ir= action.BeginInvoke(CallBack, null);
  action.EndInvoke(ir);
  }
  catch (Exception ex)
  {
  Console.WriteLine(ex.Message);
  }
  Console.ReadKey();
  }

  static void Method()
  {
  Console.WriteLine("Mehtod called in Thread:" + Thread.CurrentThread.ManagedThreadId);
  throw new Exception("Mehtod Exception in Thread:" + Thread.CurrentThread.ManagedThreadId);
  }

  static void CallBack(IAsyncResult ir)
  {
  Console.WriteLine("CallBack called in Thread:" + Thread.CurrentThread.ManagedThreadId);
  //throw new Exception("CallBack Exception in Thread:" + Thread.CurrentThread.ManagedThreadId);
   
  }
大体我有上面这样的一段代码,Method方法用通过BeginInvoke异步调用,假设Main方法在线程1上运行,Method方法在线程2上运行。当Mehtod方法在线程2上抛出异常后,线程1可以catch到这个异常(当然线程1要调用EndInvoke)。小弟有如下几个问题想求大家帮忙解释下,
第一:那回调方法CallBack是否理论也在线程2上被调用,就是线程2执行完Method方法后就执行回调方法CallBack,还是CallBack可能在另外的线程上被调用?(我程序跑下来的显示结果是:在同一线程上运行)
第二:如果回调方法CallBack在线程2上被调用,那为什么CallBack抛出异常,线程1无法catch到,而且程序直接就崩溃了?
第三:如果回调方法CallBack不在线程2上被调用,而是在另外的新线程上调用,抛错了,那我怎么处理?能把异常抛给线程1吗?
第四:为什么在如上代码中,即使Method方法抛错,回调函数依然执行?
麻烦给位大哥指点迷津,小弟学多线程,各种概念,不是越学越清晰,反而是越学越迷糊啊,不知道有什么好的方法。越学越回到原点,最基本的都模糊了。

------解决方案--------------------
第一:那回调方法CallBack是否理论也在线程2上被调用,就是线程2执行完Method方法后就执行回调方法CallBack,还是CallBack可能在另外的线程上被调用?(我程序跑下来的显示结果是:在同一线程上运行)
是的,在另一个线程上执行的。

第二:如果回调方法CallBack在线程2上被调用,那为什么CallBack抛出异常,线程1无法catch到,而且程序直接就崩溃了?
因为异常机制是本线程有效的。另外线程的异常需要单独注册System.Windows.Forms.Application.ThreadException事件

第三:如果回调方法CallBack不在线程2上被调用,而是在另外的新线程上调用,抛错了,那我怎么处理?能把异常抛给线程1吗?
忽略此问题

第四:为什么在如上代码中,即使Method方法抛错,回调函数依然执行?
这个不知道。本机没装源码。不知道.net如何实现这个的。
------解决方案--------------------
begininvoke调用后,要有一个endinvoke,endinvoke可以捕捉异常