c# – 为什么Dispatcher.BeginInvoke为ThreadStart解包TargetInvocationException而不为Action解包?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 为什么Dispatcher.BeginInvoke为ThreadStart解包TargetInvocationException而不为Action解包?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2576字,纯文字阅读大概需要4分钟。
内容图文
![c# – 为什么Dispatcher.BeginInvoke为ThreadStart解包TargetInvocationException而不为Action解包?](/upload/InfoBanner/zyjiaocheng/795/7301917687d64b97a9d3151d41353688.jpg)
考虑以下两个应用程序:
1:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Exception.GetType());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke((ThreadStart)delegate
{
throw new AccessViolationException("test");
}, DispatcherPriority.Input);
}
}
2:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Exception.GetType());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke((Action)delegate
{
throw new AccessViolationException("test");
}, DispatcherPriority.Input);
}
}
除了使用两种不同的委托类型Action和ThreadStart(虽然它们具有相同的签名)之外,两个应用程序都是相同的.
结果(输出窗口,当您使用按钮单击调用事件处理程序时)
1:System.Reflection.TargetInvocationException
2:System.AccessViolationException
为什么应用程序的行为不同?
例外#1的完整堆栈:
System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.AccessViolationException: test
bei ExceptionTest.MainWindow.<Button_Click>b__0() in c:\Users\fschmitz\Documents\Visual Studio 11\Projects\ExceptionTest\MainWindow.xaml.cs:Zeile 40.
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
bei System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
bei System.Delegate.DynamicInvokeImpl(Object[] args)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
解决方法:
我认为罪魁祸首在于ExceptionWrapper的InternalRealCall方法.更具体地说,以下部分我们有Action代表特别套装.
Action action = callback as Action;
if (action != null)
{
action();
}
else
{
// ... removed code ..
obj = callback.DynamicInvoke();
}
由于直接调用Action委托,因此产生的异常是您最初抛出的异常.对于所有其他委托类型,由于调用通过反射,异常包含在TargetInvocationException中.
总之,差异是与直接或通过反思调用所提供的代表的方式相关的副作用.
内容总结
以上是互联网集市为您收集整理的c# – 为什么Dispatcher.BeginInvoke为ThreadStart解包TargetInvocationException而不为Action解包?全部内容,希望文章能够帮你解决c# – 为什么Dispatcher.BeginInvoke为ThreadStart解包TargetInvocationException而不为Action解包?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。