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方法抛错,回调函数依然执行?
麻烦给位大哥指点迷津,小弟学多线程,各种概念,不是越学越清晰,反而是越学越迷糊啊,不知道有什么好的方法。越学越回到原点,最基本的都模糊了。
{
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上被调用,那为什么CallBack抛出异常,线程1无法catch到,而且程序直接就崩溃了?
因为异常机制是本线程有效的。另外线程的异常需要单独注册System.Windows.Forms.Application.ThreadException事件第三:如果回调方法CallBack不在线程2上被调用,而是在另外的新线程上调用,抛错了,那我怎么处理?能把异常抛给线程1吗?
忽略此问题第四:为什么在如上代码中,即使Method方法抛错,回调函数依然执行?
这个不知道。本机没装源码。不知道.net如何实现这个的。
针对第一个问题,你的回答我还是有点疑惑,为什么要在另外的线程上运行呢?我怎么能用代码证明?因为我跑来跑去结果都是在同一个线程上。而且我自己想象,回调方法为什么要在另外的线程上执行呢?回调就是在异步方法执行后就需要调用的函数,干嘛在另外的新线程上调用?虽然BeginInvoke是用线程池,比单纯新建线程要快速,但是何必要把那个线程扔回线程池,然后再取一个?(这里我又引申想问另外一个问题,难道用线程池就不要线程上下文切换了吗?)
第二个问题,Application.ThreadException没用过,去看下,呵呵,不懂再问大哥你,呵呵。但从名字上看怎么感觉是Windos Form的东西啊?在控制台应用程序上也能用吗?
Delegate.Invoke用于再当前线程上执行一个委托。我们知道委托是一个函数或方法的引用,Delegate.Invoke就是调用方法或函数的机制。
Delegate.BeginInvoke
Delegate.BeginInvoke用来异步执行一个委托,在一个单独的线程中执行,所以不会阻塞当前的线程。在调用Delegate.BiginInvoke后,需要在某个时刻调用EndInvoke以避免资源泄露。由于委托方法是在单独的线程中,所以不能更新UI线程的属性或者调用任何潜在更新UI的方法。比方说,如果想要更新一个进度条,填充一个列表或其他类似的工作,必须使用一个不同的机制:Control.Invoke或Control.BeginInvoke
begininvoke是在一个单独的线程中执行的不同于invoke
谢谢各位了!
那不是说,回调方法和异步方法是在同一个线程执行的吗?我现在迷糊了。
还有关于昨天怎么让线程1知道线程2,“因为异常机制是本线程有效的。另外线程的异常需要单独注册System.Windows.Forms.Application.ThreadException事件”这个对我启发比较大,呵呵,我发现自己注册个事件也可以的,可以通过事件通知,谢谢大哥啊!