• 异常处理


    未知异常处理

          对于未知异常,系统采用全局统一捕获的方式进行。一般情况下,代码中不会出现try...catch代码段。当发生未知异常时系统将其类型、操作人账号、以及异常内容存入数据表中。全局统一捕获写在Program类中,代码如下:

            /// <summary>
            
    /// 统一捕获异常,非UI线程
            
    /// </summary>
            
    /// <param name="sender">sender</param>
            
    /// <param name="e">异常</param>
            static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                if (e.ExceptionObject is System.Exception)
                {
                    CommonService.CommonClient systemLog = new CommonService.CommonClient();
                    systemLog.SaveLogInfo(e.ExceptionObject.ToString(), LoginInfo.CurrentUser.Account, e.ExceptionObject.GetType().ToString());
                    systemLog.Close();
                    CSMS2.Infrastructure.Helpers.AlterHelper.MessageBoxShowError(e.ExceptionObject.ToString());
                }
            }

            /// <summary>
            
    /// 统一捕获异常,UI线程
            
    /// </summary>
            
    /// <param name="sender">sender</param>
            
    /// <param name="e">异常</param>
            static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                CommonService.CommonClient systemLog = new CommonService.CommonClient();
                systemLog.SaveLogInfo(e.Exception.ToString(), LoginInfo.CurrentUser.Account, e.Exception.GetType().ToString());
                systemLog.Close();
                CSMS2.Infrastructure.Helpers.AlterHelper.MessageBoxShowError(e.Exception.ToString());
            }

          由此可见对于所有的除数据库连接方面的异常,系统都会将异常信息记录数据库。这样可以比较方便的进行查询,对于数据连接方面的问题,系统判断出后,会在右下角提示“您已断网”。

    已知异常

         对于已知异常,系统做法比较复杂。因为已知的异常都是由开发人员根据需要,做特定处理的。框架规定了一些特殊类型,必须调用什么方法。下面一一举例说明:

    • WCF的异常处理

         对于WCF的客户端调用,都会使用类似如下方式进行:

                    BiaoWuGLService.IBiaoWuGL client = ServiceProxyFactory.Create<BiaoWuGLService.IBiaoWuGL>("BasicHttpBinding_IBiaoWuGL");
                    DataTable dt = client.FuHeDJ_ChaXun(searchDTO);

    这时ServiceProxyFactory工厂类会自动进行异常的捕获和处理,这样就避免了每个开发人员都手工的写一大堆冗余的try...catch代码段。

    那么ServiceProxyFactory工厂类是怎么进行异常处理的那,让我们看下代码片段:

            /// <summary>
            
    /// 重写调用方法
            
    /// </summary>
            
    /// <param name="msg">通讯数据信息</param>
            
    /// <returns></returns>
            public override IMessage Invoke(IMessage msg)
            {
                T channel = ChannelFactoryCreator.Create<T>(this._endpointName).CreateChannel();
                IMethodCallMessage methodCall = (IMethodCallMessage)msg;
                IMethodReturnMessage methodReturn = null;
                object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[];
                methodCall.Args.CopyTo(copiedArgs, 0);
                try
                {
                    object returnValue = methodCall.MethodBase.Invoke(channel, copiedArgs);
                    methodReturn = new ReturnMessage(returnValue, copiedArgs, copiedArgs.Length, methodCall.LogicalCallContext, methodCall);
                    (channel as ICommunicationObject).Close();
                }
                catch (Exception ex)
                {
                    if (ex.InnerException is CommunicationException || ex.InnerException is TimeoutException)
                    {
                        (channel as ICommunicationObject).Abort();
                    }
                    if (ex.InnerException != null)
                    {
                        methodReturn = new ReturnMessage(ex.InnerException, methodCall);
                    }
                    else
                    {
                        methodReturn = new ReturnMessage(ex, methodCall);
                    }
                }
                return methodReturn;
            }

      由上面代码可以看出,当发生超时或通信异常时,代理会调用终止方法。否则会抛出对应的异常。

    • 对于事务的异常处理

         通常当事务发生异常时,都要回滚所有操作。由此框架通过委托方法提供了一些通用的方法供开发人员调用。

            /// <summary>
            
    /// 回调函数,可以不写try catch代码
            
    /// </summary>
            
    /// <param name="account"></param>
            
    /// <param name="func"></param>
            
    /// <returns></returns>
            public static bool InvokeOracleTransaction(string account, Func<OracleTransaction, bool> func)
            {
                bool result = false;
                using (OracleConnection conn = new OracleConnection(Platform.Configuration.ConfigHelper.BusinessConnString))
                {
                    conn.Open();
                    OracleTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted);

                    try
                    {
                        result = func(tran);
                        if (result)
                        {
                            tran.Commit();
                        }
                        else
                        {
                            tran.Rollback();
                        }
                    }
                    catch (Exception ex)
                    {
                        SystemLog.SaveLogInfo(ex.ToString(), account, ex.GetType().ToString());
                        tran.Rollback();
    #if DEBUG
                        throw ex;
    #else
                        return false;
    #endif
                    }
                }
                return result;
            }

    由上可以发现,当事务异常时会回滚所有操作,并记录日志。开发人员只需调用该方法,并传入相应的事务和方法即可。

    • 一些控件的异常

         比如扫描控件、Grid控件系统都会将原异常捕获,然后加上特殊的中文描述,使得客户和开发人员能够比较方便的判断异常的成因。

                    try
                    {
                        // 设置鼠标
                        this.Cursor = Cursors.Default;

                        // 抹去框架
                        
    //Graphics g = this.CreateGraphics();
                        
    //DrawSelectionFrame(g);
                        
    //g.Dispose();

                        
    // 标准化点
                        NormalizePoints(ref startImgP, ref endImgP);

                        size.Width = endImgP.X - startImgP.X + 1;
                        size.Height = endImgP.Y - startImgP.Y + 1;
                        rec.Size = size;
                        Crop cp = new Crop(rec);
                        // 剪切图像
                        ApplyFilter(cp);
                    }
                    catch (Exception ex)
                    {
                        if (this.languageType == "zh-CN")
                            MessageBox.Show("对不起!切图出错:" + ex.Message, "系统提示");
                        else
                            MessageBox.Show("Cutting image error:" + ex.Message, "System Information"); 
                    
                    }
    • 一般的业务操作的异常

         对于一般业务操作,系统会记录异常,并将message向上抛出,然后由对应的界面决定到底返回什么错误信息给客户。这里的message已经是经过加工后的消息了,具体怎么加工是由开发人员根据情况处理的。

            /// <summary>
            
    /// 工单登记
            
    /// </summary>
            
    /// <param name="message"></param>
            
    /// <param name="dto"></param>
            
    /// <param name="login"></param>
            
    /// <returns></returns>
            public static bool DengJi(out string message, FuHeDJDTO dto, Entity.BW_YUYUEXX yuyuexx, UploadEntity[] uploadEntityList, Entity.LoginInfo login)

         上面是对于工单登记的方法接口,如有错误会已out message的形式返回。

  • 相关阅读:
    经济危机下,自主创业已成为一种时代潮流?
    曾靖雯(帮别人名字作诗)
    四大内伤造就80后创业高失败率
    如何让创业的路不再崎岖
    叶莉(帮别人名字作诗)
    谁能够在萧条中生存?历史总是惊人相似的(转)
    哪种书最适合创业者阅读
    中西部崛起 关键是要激发普遍的创业热情
    每日英语:Dating in China Is a Largely Commercial Transaction
    每日英语:Poor Chinese Schools Tell Students: Bring Your Own Desks
  • 原文地址:https://www.cnblogs.com/zyizyizyi/p/2669195.html
Copyright © 2020-2023  润新知