本文主要是介绍【wpf】Application与AppDomain(未完成,待完善),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Application 实现单一实例模式,以提供对其窗口、属性和资源范围服务的共享访问权限。 因此,每个 AppDomain(应用程序域)中仅且只有一个 Application 实例存在。
我们在写WPF的程序的时候,你根本没有创建Application与AppDomain的对象,但是你已经可以使用它们的对象了。
跳到App内部,可以看到如下代码(这段代码是VS自动生成的)。
这让我想到了MFC中的theApp,它管理了整个应用程序的流程。
继承关系:
Application 是封装 WPF 应用程序特定功能的类,包括:
-
应用程序生存期:Activated、、Current、、RunSessionEndingDeactivatedExitShutdownDispatcherUnhandledException、。 StartupShutdownMode
-
应用程序范围窗口、属性和资源管理:FindResource、、GetContentStream、、GetResourceStream、LoadComponent、MainWindowProperties、Resources、StartupUri。 Windows
-
命令行参数和退出代码处理:Application.Startup、、Application.ExitApplication.Shutdown。
-
导航:FragmentNavigation、、LoadCompleted、Navigated、NavigationProgressNavigating、NavigationStoppedNavigationFailed、、SetCookie。 GetCookie
AppDomain 像是Application的运行容器。一个进程可以创建多个AppDomain。AppDomain一般用于插件模式。这样主程序可以动态的加载可卸载其他AppDomain(插件),插件的崩溃也不会影响主程序。
下面是Application 和 AppDomain 常用的一些地方的小结:
Application 和 AppDomain 可用于,全局异常捕获!我们自定义的异常也是可以捕获到。
public App(){//UI线程异常this.DispatcherUnhandledException += App_DispatcherUnhandledException;//非UI线程异常AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;}/// <summary>/// UI线程异常/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <exception cref="NotImplementedException"></exception>private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e){e.Handled = true; // 消息不再继续往下流了(会流到,CurrentDomain_UnhandledException 非UI线程异常处理)string msg = e.Exception.Message;string func_name = e.Exception.TargetSite.Name;string str_err = $"错误信息:{msg},| 调用方法:{func_name}";logger.Error(str_err);MessageBox.Show(str_err);//throw new NotImplementedException();}/// <summary>/// 非UI线程异常/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <exception cref="NotImplementedException"></exception>private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e){logger.Error(e.ExceptionObject);throw new NotImplementedException();}
如果想在子线程里,更新界面信息,我们可以用到Application.Current.Dispatcher
在WPF中,所有的WPF对象都派生自DispatcherObject,DispatcherObject暴露了Dispatcher属性用来取得创建 对象线程对应的Dispatcher。DispatcherObject对象只能被创建它的线程所访问,其他线程修改 DispatcherObject需要取得对应的Dispatcher,调用Invoke或者BeginInvoke来投入任务。(Invoke和BeginInvoke等从WinForm时代就是一直存在的,WPF使用了Dispatcher来封装这些线程级的操作。原理和就是WINAPI中的PostMessage)
private void GuiHandler(){ushort CardID = 0;while (LoopGui){Application.Current.Dispatcher.BeginInvoke(new Action(() =>{// 改变界面UI// 相当于将更新消息投递到,界面处理消息队列}));Thread.Sleep(500);}}
在程序的任何地方调用System.Windows.Application.Current(Application类型),都能得到app对象,不过记得将其转换成我们自己的App的类型!
这篇关于【wpf】Application与AppDomain(未完成,待完善)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!