wpf 单例模式和异常处理

来源:互联网 发布:步科触摸屏编程软件 编辑:程序博客网 时间:2024/05/17 06:22

第一次写博客,如有错误,请大家及时告知,本人立即改之。

如果您有好的想法或者建议,我随时与我联系。

如果发现代码有误导时,请与我联系,我立即改之。


好了不多说,直接贴代码。


一般的错误,使用下面两个就可以了。我不太赞同项目里面大量使用try{}catch{}(释放资源除外)

            //处理UI线程异常            Application.Current.DispatcherUnhandledException += App_DispatcherUnhandledException;            //处理非UI线程异常            AppDomain.CurrentDomain.UnhandledException += App_CurrentDomainUnhandledException;


特殊情况下,此函数可检测到c++封装的dll(不是百分之百可以检测到)

        public delegate int CallBack(ref long a);        CallBack myCall;        [DllImport("kernel32")]        private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);        
       myCall = new CallBack(ExceptionFilter);       SetUnhandledExceptionFilter(myCall);
此函数可让程序"美化"结束。

完整代码:

    public partial class App : Application    {        public delegate int CallBack(ref long a);        CallBack myCall;        [DllImport("kernel32")]        private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);        Mutex mutex;        public App()        {            Startup += new StartupEventHandler(App_Startup);        }        void App_Startup(object sender, StartupEventArgs e)        {            bool ret;            mutex = new System.Threading.Mutex(true, "{wpf-8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}", out ret);            if (!ret)            {                Environment.Exit(0);                return;            }            Log4net.Init(typeof(MainWindow));            //处理UI线程异常            Application.Current.DispatcherUnhandledException += App_DispatcherUnhandledException;            //处理非UI线程异常            AppDomain.CurrentDomain.UnhandledException += App_CurrentDomainUnhandledException;            myCall = new CallBack(ExceptionFilter);            SetUnhandledExceptionFilter(myCall);                    }        void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)        {            Log4net.gLogger.Error("--<App_DispatcherUnhandledException>--" + e.Exception.ToString());            System.Windows.Forms.MessageBox.Show(e.Exception.ToString(),                "Error",                System.Windows.Forms.MessageBoxButtons.OK,                System.Windows.Forms.MessageBoxIcon.Error);            e.Handled = true;        }        void App_CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)        {            Log4net.gLogger.Fatal("--<App_CurrentDomainUnhandledException>--" + e.ExceptionObject.ToString());            if (System.Windows.Forms.DialogResult.Yes                == System.Windows.Forms.MessageBox.Show(                "软件出现不可恢复错误,即将关闭。是否选择生成Dump文件以供开发人员分析问题?",                "Error", System.Windows.Forms.MessageBoxButtons.YesNo,                System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1))            {                WriteDump();            }            Environment.Exit(0);        }        private int ExceptionFilter(ref long a)        {            Log4net.gLogger.Fatal("--<ExceptionFilter>--" + Environment.StackTrace);            WriteDump();            return 1;        }        private void WriteDump()        {            Dump.WriteDumpFile();        }    }


对于一些问题,我们可以通过日志文件记录(我目前使用Log4net)。有时候日志不能完全帮助我们找到问题所在,这时dmp文件就可以帮助到我们。


    internal class DumpWriter    {        public enum MiniDumpType        {            None = 0x00010000,            Normal = 0x00000000,            WithDataSegs = 0x00000001,            WithFullMemory = 0x00000002,            WithHandleData = 0x00000004,            FilterMemory = 0x00000008,            ScanMemory = 0x00000010,            WithUnloadedModules = 0x00000020,            WithIndirectlyReferencedMemory = 0x00000040,            FilterModulePaths = 0x00000080,            WithProcessThreadData = 0x00000100,            WithPrivateReadWriteMemory = 0x00000200,            WithoutOptionalData = 0x00000400,            WithFullMemoryInfo = 0x00000800,            WithThreadInfo = 0x00001000,            WithCodeSegs = 0x00002000        }        [DllImport("DbgHelp.dll")]        private static extern bool MiniDumpWriteDump(            IntPtr hProcess,            Int32 processId,            IntPtr fileHandle,            MiniDumpType dumpType,            ref MiniDumpExceptionInformation excepInfo,            IntPtr userInfo,            IntPtr extInfo);        [DllImport("DbgHelp.dll")]        private static extern bool MiniDumpWriteDump(            IntPtr hProcess,            Int32 processId,            IntPtr fileHandle,            MiniDumpType dumpType,            IntPtr excepParam,            IntPtr userInfo,            IntPtr extInfo);        [StructLayout(LayoutKind.Sequential, Pack = 4)]// Pack=4 is important! So it works also for x64!        private struct MiniDumpExceptionInformation        {            public uint ThreadId;            public IntPtr ExceptionPointers;            [MarshalAs(UnmanagedType.Bool)]            public bool ClientPointers;        }        [DllImport("kernel32.dll")]        private static extern uint GetCurrentThreadId();        private bool WriteDump(String dmpPath, MiniDumpType dmpType)        {            using (FileStream stream = new FileStream(dmpPath, FileMode.Create))            {                //取得进程信息                Process process = Process.GetCurrentProcess();                MiniDumpExceptionInformation mei = new MiniDumpExceptionInformation();                mei.ThreadId = GetCurrentThreadId();                mei.ExceptionPointers = Marshal.GetExceptionPointers();                mei.ClientPointers = true;//false时 mei.ExceptionPointers==                bool res = false;                //如果不使用MiniDumpWriteDump重载函数                //当mei.ExceptioonPointers == IntPtr.Zero => 无法保存dmp文件                //且当mei.ClientPointers == false时程序直接崩溃(mei.ClientPointers == true程序不崩溃)                //                //以上测试信息硬件环境 cpu Pentium(R) Dual-Core CPU T4200 @ 2.00GHz                //                 vs2013update5                //在公司服务器上测试(64位系统、vs2013)不会出现上述情况                /*res = MiniDumpWriteDump(                    process.Handle,                    process.Id,                    stream.SafeFileHandle.DangerousGetHandle(),                    dmpType,                    ref mei,                    IntPtr.Zero,                    IntPtr.Zero);*/                if (mei.ExceptionPointers == IntPtr.Zero)                {                    res = MiniDumpWriteDump(                        process.Handle,                        process.Id,                        stream.SafeFileHandle.DangerousGetHandle(),                        dmpType,                        IntPtr.Zero,                        IntPtr.Zero,                        IntPtr.Zero);                }                else                {                    res = MiniDumpWriteDump(                        process.Handle,                        process.Id,                        stream.SafeFileHandle.DangerousGetHandle(),                        dmpType,                        ref mei,                        IntPtr.Zero,                        IntPtr.Zero);                }                return res;            }        }        public DumpWriter()        {            FilePath = Environment.CurrentDirectory + @"\Dump";            if (!Directory.Exists(FilePath))                Directory.CreateDirectory(FilePath);        }        /// <summary>        /// 保存dmp文件路径        /// </summary>        public string FilePath { get; protected set; }        /// <summary>        /// 保存dmp文件名称(包括路径)        /// </summary>        public string FileName { get; protected set; }        /// <summary>        /// 写dmp文件        /// </summary>        /// <param name="dmpType">参数,不同参数保存内容不一样</param>        /// <returns></returns>        public bool WriteDumpFile(MiniDumpType dmpType)        {            FileName = string.Format("{0}\\{1}_{2}.dmp",                FilePath,                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff"),                Process.GetCurrentProcess().ProcessName);            return WriteDump(FileName, dmpType);        }    }

好了,就写这么多吧。一般情况下,这些应该可以帮助我们解决大部分问题了。



源码

点击打开链接

0 0
原创粉丝点击