【wpf】Application与AppDomain(未完成,待完善)

Application 实现单一实例模式,以提供对其窗口、属性和资源范围服务的共享访问权限。 因此,每个 AppDomain(应用程序域)中仅且只有一个 Application 实例存在。

我们在写WPF的程序的时候,你根本没有创建Application与AppDomain的对象,但是你已经可以使用它们的对象了。

跳到App内部,可以看到如下代码(这段代码是VS自动生成的)。

这让我想到了MFC中的theApp,它管理了整个应用程序的流程。

继承关系:

Application 是封装 WPF 应用程序特定功能的类,包括:

 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的类型!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code bean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值