编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> Windows Phone -> 【转】UWP 捕获全局异常 -> 正文阅读

[Windows Phone]【转】UWP 捕获全局异常

转自:http://www.cnblogs.com/youngytj/p/4749004.html
异步(async)方法中的异常无法被App的UnhandledException捕获的问题
这是一个比较严重的问题.目前已知很多的做法就是局部try catch来解决这个问题.这样做是很容易导致Process被强制终止然后引起闪退的问题的.
我这里用了一个线程同步模型类解决这个问题.

using System;
using System.Threading;
using Windows.UI.Xaml.Controls;

namespace AiJianShu.ExceptionHandler
{
    internal class ExceptionHandlingSynchronizationContext : SynchronizationContext
    {
        /// <summary>
        /// 注册事件.  需要在OnLaunched和OnActivated事件中调用
        /// </summary>
        /// <returns></returns>
        public static ExceptionHandlingSynchronizationContext Register()
        {
            var syncContext = Current;
            if (syncContext == null)
                throw new InvalidOperationException("Ensure a synchronization context exists before calling this method.");


            var customSynchronizationContext = syncContext as ExceptionHandlingSynchronizationContext;


            if (customSynchronizationContext == null)
            {
                customSynchronizationContext = new ExceptionHandlingSynchronizationContext(syncContext);
                SetSynchronizationContext(customSynchronizationContext);
            }


            return customSynchronizationContext;
        }

        /// <summary>
        /// 将线程的上下文绑定到特定的Frame上面
        /// </summary>
        /// <param name="rootFrame"></param>
        /// <returns></returns>
        public static ExceptionHandlingSynchronizationContext RegisterForFrame(Frame rootFrame)
        {
            if (rootFrame == null)
                throw new ArgumentNullException("rootFrame");

            var synchronizationContext = Register();

            rootFrame.Navigating += (sender, args) => EnsureContext(synchronizationContext);
            rootFrame.Loaded += (sender, args) => EnsureContext(synchronizationContext);

            return synchronizationContext;
        }

        private static void EnsureContext(SynchronizationContext context)
        {
            if (Current != context)
                SetSynchronizationContext(context);
        }


        private readonly SynchronizationContext _syncContext;


        public ExceptionHandlingSynchronizationContext(SynchronizationContext syncContext)
        {
            _syncContext = syncContext;
        }


        public override SynchronizationContext CreateCopy()
        {
            return new ExceptionHandlingSynchronizationContext(_syncContext.CreateCopy());
        }


        public override void OperationCompleted()
        {
            _syncContext.OperationCompleted();
        }


        public override void OperationStarted()
        {
            _syncContext.OperationStarted();
        }


        public override void Post(SendOrPostCallback d, object state)
        {
            _syncContext.Post(WrapCallback(d), state);
        }


        public override void Send(SendOrPostCallback d, object state)
        {
            _syncContext.Send(d, state);
        }


        private SendOrPostCallback WrapCallback(SendOrPostCallback sendOrPostCallback)
        {
            return state =>
            {
                try
                {
                    sendOrPostCallback(state);
                }
                catch (Exception ex)
                {
                    if (!HandleException(ex))
                        throw;
                }
            };
        }

        private bool HandleException(Exception exception)
        {
            if (UnhandledException == null)
                return false;

            var exWrapper = new AysncUnhandledExceptionEventArgs
            {
                Exception = exception
            };

            UnhandledException(this, exWrapper);

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
            if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
#endif
            return exWrapper.Handled;
        }

        public event EventHandler<AysncUnhandledExceptionEventArgs> UnhandledException;
    }

    public class AysncUnhandledExceptionEventArgs : EventArgs
    {
        public bool Handled { get; set; }
        public Exception Exception { get; set; }
    }
}

使用实例:

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;

    this.UnhandledException += App_UnhandledException;

}

private void RegisterExceptionHandlingSynchronizationContext()
{
    ExceptionHandlingSynchronizationContext
        .Register()
        .UnhandledException += SynchronizationContext_UnhandledException;
}

private async void App_UnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
    e.Handled = true;

    await new MessageDialog("Application Unhandled Exception:\r\n" + e.Exception.Message)
        .ShowAsync();
}

private async void SynchronizationContext_UnhandledException(object sender, AysncUnhandledExceptionEventArgs e)
{
    e.Handled = true;

    await new MessageDialog("Synchronization Context Unhandled Exception:\r\n" + e.Exception.Message)
        .ShowAsync();
}

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    RegisterExceptionHandlingSynchronizationContext();

#if DEBUG
    if (System.Diagnostics.Debugger.IsAttached)
    {
        this.DebugSettings.EnableFrameRateCounter = true;
    }
#endif

    Frame rootFrame = Window.Current.Content as Frame;

    // 不要在窗口已包含内容时重复应用程序初始化,
    // 只需确保窗口处于活动状态
    if (rootFrame == null)
    {
        // 创建要充当导航上下文的框架,并导航到第一页
        rootFrame = new Frame();

        rootFrame.NavigationFailed += OnNavigationFailed;

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: 从之前挂起的应用程序加载状态
        }

        // 将框架放在当前窗口中
        Window.Current.Content = rootFrame;
    }

    if (rootFrame.Content == null)
    {
        // 当导航堆栈尚未还原时,导航到第一页,
        // 并通过将所需信息作为导航参数传入来配置
        // 参数
        rootFrame.Navigate(typeof(MainPage), e.Arguments);
    }
    // 确保当前窗口处于活动状态
    Window.Current.Activate();
}

protected override void OnActivated(IActivatedEventArgs args)
{
    RegisterExceptionHandlingSynchronizationContext();
    base.OnActivated(args);
}

  Windows Phone 最新文章
[UWP] 自定义一个ItemsPanel
WP8.1程序开发中,如何加载本地文件资源或安
UWP 律师信息 MVVM 2.0版本
Win10 FaceAPI小demo开发问题汇总
【转】UWP 捕获全局异常
x:bind不支持样式文件 或 此Xaml文件必须又
WP模拟器修改语言为中文方法
wp仿系统截图
Windows Phone 8 锁屏背景与通知
博客园新闻WP8.1客户端
上一篇文章      下一篇文章      查看所有文章
加:2017-01-13 15:01:57  更:2017-05-17 02:44:54 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年12日历
2019-12-8 8:00:46
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识