想接网站自己做,陕西省住房建设厅官网,那里有做网站,网站开发规范文档什么是异常#xff1f;
在C#中#xff0c;异常是在程序执行过程中发生的特殊情况#xff0c;例如尝试除以零、访问不存在的文件、网络连接中断等。这些情况会中断程序的正常流程。
当C#程序中发生这种特殊情况时#xff0c;会创建一个异常对象并将其抛出。这个异常对象包…什么是异常
在C#中异常是在程序执行过程中发生的特殊情况例如尝试除以零、访问不存在的文件、网络连接中断等。这些情况会中断程序的正常流程。
当C#程序中发生这种特殊情况时会创建一个异常对象并将其抛出。这个异常对象包含了关于异常的详细信息如异常类型和异常发生时的程序状态。
异常处理是一个重要的编程概念它允许程序员在异常发生时采取适当的行动而不是让程序崩溃。在C#中我们使用trycatch和finally关键字来处理异常。
比如下面的代码用0除一个数时会出现一个异常
internal class Program
{static void Main(string[] args){int x 10, y 0;x / y;}
}try语句
try语句用来指明为避免出现异常而被保护的代码段并在发生异常时提供代码处理异常。try语句由3个部分组成如下图所示 处理异常
上面除以0会导致一个异常的程序可以进行如下改写进行异常处理
internal class Program
{static void Main(string[] args){int x 10;try{int y 0;x / y;}catch{Console.WriteLine(Handling all exceptions);}}
}异常被捕获 异常类
在C#中所有的异常都是派生自System.Exception类的。System.Exception类是所有异常的基类它提供了一些基本的功能如返回错误消息和记录异常发生的堆栈跟踪。 C#提供了一些内置的异常类用于表示常见的异常情况。例如
System.NullReferenceException当你试图访问一个null对象的成员时会抛出这个异常。System.DivideByZeroException当你试图除以零时会抛出这个异常。System.IndexOutOfRangeException当你试图访问数组或集合的无效索引时会抛出这个异常。System.IO.FileNotFoundException当试图打开的文件不存在时会抛出这个异常。
当一个异常发生时CLR会创建该类型的异常对象并寻找适当的catch子句处理它。
所有异常类从根本上派生自System.Exception类异常继承层次的一个部分如下所示 catch子句
catch子句处理异常。它有3种形式允许不同级别的处理如下图所示 一般catch子句这种形式的catch子句可以捕获任何类型的异常。它不指定异常类型所以它会捕获try块中抛出的所有异常。特定catch子句这种形式的catch子句只捕获指定类型的异常。如果try块中抛出的异常类型与catch子句中指定的类型匹配那么就会执行这个catch子句。带对象的特定catch子句这种形式的catch子句不仅指定了异常类型还定义了一个异常对象。这个异常对象可以用来访问关于异常的更多信息如错误消息和堆栈跟踪。
将开头的例子修改为使用带对象的特定catch子句如下所示 internal class Program{static void Main(string[] args){int x 10;try{int y 0;x / y;}catch(DivideByZeroException e){Console.WriteLine($Message:{e.Message});Console.WriteLine($Source: {e.Source});Console.WriteLine($Stack: {e.StackTrace});} }}输出结果如下所示 抛出异常
可以使用throw语句使代码显式地引发一个异常。throw语句的语法如下
throw ExceptionObject;好了以上就是C#中关于异常处理的基础知识现在我们结合WPF中的例子说明在WPF中如何进行异常处理的。
WPF中的异常处理
现在来看看ExceptionHandlingSecondaryUIThread这个例子项目结构如下图所示 先来看一下这个项目的运行效果 这个例子介绍了WPF中如何处理在辅助UI线程中发生的异常。
现在来看看是如何处理的。
StartSecondaryUIThreadButton按钮点击事件处理程序 private void startSecondaryUIThreadButton_Click(object sender, RoutedEventArgs e){// Creates and starts a secondary thread in a single threaded apartment (STA)var thread new Thread(MethodRunningOnSecondaryUIThread);thread.SetApartmentState(ApartmentState.STA);thread.IsBackground true;thread.Start();}这段代码的主要目的是创建并启动一个新的辅助UI线程。 thread.SetApartmentState(ApartmentState.STA);这行代码设置了线程的公寓状态为STASingle-Threaded Apartment。在WPF中所有的UI线程都必须是STA线程因为UI元素不是线程安全的。
Single-Threaded ApartmentSTA介绍
在WPFWindows Presentation Foundation中Single-Threaded ApartmentSTA是指一个线程模型其中每个线程都维护自己的消息队列并且所有的UI操作都在这个线程上进行。 在STA模型中每个线程都有自己的内存空间这意味着线程之间的数据不会共享从而避免了多线程编程中的许多并发问题。这对于UI编程来说非常重要因为UI元素通常不是线程安全的所以所有的UI操作都必须在同一个线程上进行。 在WPF中主UI线程默认就是一个STA线程。此外你也可以创建其他的STA线程但是每个STA线程都只能操作它自己创建的UI元素。
MethodRunningOnSecondaryUIThread方法如下所示 // THIS METHOD RUNS ON A SECONDARY UI THREAD (THREAD WITH A DISPATCHER)private void MethodRunningOnSecondaryUIThread(){var secondaryUiThreadId Thread.CurrentThread.ManagedThreadId;try{// On secondary thread, show a new Window before starting a new Dispatcher// ie turn secondary thread into a UI threadvar window new SecondaryUIThreadWindow();window.Show();Dispatcher.Run();}catch (Exception ex){// Dispatch the exception back to the main ui thread and reraise itApplication.Current.Dispatcher.Invoke(DispatcherPriority.Send,(DispatcherOperationCallback) delegate{// THIS CODE RUNS BACK ON THE MAIN UI THREADstring msg $Exception forwarded from secondary UI thread {secondaryUiThreadId}.;throw new Exception(msg, ex);}, null);// NOTE - Application execution will only continue from this point// onwards if the exception was handled on the main UI thread// by Application.DispatcherUnhandledException}}在try语句块中创建了SecondaryUIThreadWindow。
SecondaryUIThreadWindow上的按钮的点击事件处理程序如下所示 private void raiseExceptionOnSecondaryUIThreadButton_Click(object sender, RoutedEventArgs e){// Raise an exception on the secondary UI threadstring msg $Exception raised on secondary UI thread {Dispatcher.Thread.ManagedThreadId}.;throw new Exception(msg);}抛出了一个异常。
这个异常被MethodRunningOnSecondaryUIThread方法中的catch子句段捕获 Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,(DispatcherOperationCallback) delegate{// THIS CODE RUNS BACK ON THE MAIN UI THREADstring msg $Exception forwarded from secondary UI thread {secondaryUiThreadId}.;throw new Exception(msg, ex);}, null);这段代码的主要目的是在辅助UI线程上捕获异常并将异常转发到主UI线程上进行处理。
在app.xaml中 DispatcherUnhandledExceptionApp_DispatcherUnhandledException这行代码是在WPF应用程序中设置全局未处理异常的处理器。
当应用程序的主调度器捕获到未处理的异常时App_DispatcherUnhandledException方法会被调用来处理这个异常。 这是一种处理全局未处理异常的方式可以防止应用程序因为未处理的异常而崩溃。在App_DispatcherUnhandledException方法中你可以记录异常信息显示错误消息或者决定是否让应用程序继续运行。 private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e){// Display exception messagevar sb new StringBuilder();sb.AppendFormat({0}\n, e.Exception.InnerException.Message);sb.AppendFormat({0}\n, e.Exception.Message);sb.AppendFormat(Exception handled on main UI thread {0}., e.Dispatcher.Thread.ManagedThreadId);MessageBox.Show(sb.ToString());// Keep application running in the face of this exceptione.Handled true;}这样就完成了在WPF中的辅助UI线程的异常处理。
还有一个例子是ExceptionHandlingSecondaryWorkerThread说明在WPF中如何处理在辅助工作线程Secondary Worker Thread中发生的异常与这个例子类似。
参考
1、《C#图解教程》
2、[WPF-Samples/Application Management/ExceptionHandlingSecondaryUIThread at main · microsoft/WPF-Samples (github.com)](https://github.com/microsoft/WPF-Samples/tree/main/Application Management/ExceptionHandlingSecondaryUIThread)