大侠“fangxinggood”说:
有点多事,在UI层的事件处理中没有Try,Catch这样导致Application轻易就崩溃。
而且不能Log错误堆栈,不方便错误调查。应该加上。
在下不经常使用“Try  Catch”语句,不熟悉它的功能。只知道他是抛出异常然后捕获异常,进行处理。问题1:Try  Catch语句怎样使用?
问题2:Try Catch语句有什么功能?
问题3:何为“UI”层,就是用户操作界面?
问题4:“不能Log错误堆栈”,什么是“Log错误”

解决方案 »

  1.   

    显然不只是UI层,任何可能出现错误而你设计时必然无法左右的地方,都可以用try,catch。
    电脑上本没有异常机制,就像c++中不限制一个字节的byte等于255时依然可以执行加1操作一样。异常机制是一种额外的保护机制,当你的软件需要时,可以通过throw new Exception()抛出异常,以一种非正常结束的状态结束函数调用通知调用方,调用的地方如果没有使用try,catch捕获异常,则继续向上抛出直到最终呈献给用户一个红色的叉叉,和一堆例如:程序异常关闭,请联系xxxx等的字样。
    try catch就是为了捕获异常的。
    例如try
    {
        //可能异常的代码,例如
        object o = new object();
        o = null;
        MessageBox.Show(o.GetType().Name);//这里o是null会有NullRefranceException
    }
    catch(Exception ex)
    {
        //你这里捕获到异常了,可以考虑记录到文件中,以便后续查找错误,也可以其他方式处理
        File.AppendAllText("errorlog.txt",ex.Message);
    }
      

  2.   

    try catch
    就是可能会出错的代码块用这个包起来,
    这样就能抛出异常,可以检查代码,一般的书籍都有介绍的,这个功能挺长的,
    LZ最好可以去找本书籍看看.
      

  3.   

    try catch
    调试的时候很好用
    有些错误无法找到的时候,在认为可能错误的地方用try catche找错误很方便
    能够一目了然的知道是什么错误
      

  4.   

    是一种错误处理机制
    比如
    try
    {
    代码
    }
    catch(Exception e)
    {
     
    }
    假如代码中有异常 加上try catch后也不会导致程序崩盘,没加的话,就会崩盘
    何为“UI”层,就是用户操作界面,user interface 的简写
      

  5.   

    try-catch 语句由一个 try 块后跟一个或多个 catch 子句构成,这些子句指定不同的异常处理程序。 备注
    --------------------------------------------------------------------------------try 块包含可能导致异常的保护代码。该块一直执行到引发异常或成功完成为止。例如,下列强制转换 null 对象的尝试引发 NullReferenceException 异常:object o2 = null;
    try
    {
        int i2 = (int)o2;   // Error
    }
    catch 子句使用时可以不带任何参数,这种情况下它捕获任何类型的异常,并被称为一般 catch 子句。它还可以接受从 System.Exception 派生的对象参数,这种情况下它处理特定的异常。例如:catch (InvalidCastException e) 
    {
    }
    在同一个 try-catch 语句中可以使用一个以上的特定 catch 子句。这种情况下 catch 子句的顺序很重要,因为会按顺序检查 catch 子句。将先捕获特定程度较高的异常,而不是特定程度较小的异常。 在 catch 块中可以使用 throw 语句再次引发已由 catch 语句捕获的异常。例如:catch (InvalidCastException e) 
    {
        throw (e);    // Rethrowing exception e
    }如果要再次引发当前由无参数的 catch 子句处理的异常,则使用不带参数的 throw 语句。例如:catch
    {
        throw;
    }在 try 块内部时应该只初始化其中声明的变量;否则,完成该块的执行前可能发生异常。例如,在下面的代码示例中,变量 x 在 try 块内初始化。试图在 Write(x) 语句中的 try 块外部使用此变量时将产生编译器错误:使用了未赋值的局部变量。static void Main() 
    {
        int x;
        try 
        {
            // Don't initialize this variable here.
            x = 123;
        }
        catch
        {
        }
        // Error: Use of unassigned local variable 'x'.
        Console.Write(x);
    }有关 catch 块的更多信息,请参见 try-catch-finally。示例
    --------------------------------------------------------------------------------在此例中,try 块包含对可能导致异常的 MyMethod() 方法的调用。catch 子句包含仅在屏幕上显示消息的异常处理程序。当从 MyMethod 内部调用 throw 语句时,系统查找 catch 语句并显示 Exception caught 消息。复制// try_catch_example.cs
    using System;
    class MainClass
    {
        static void ProcessString(string s)
        {
            if (s == null)
            {
                throw new ArgumentNullException();
            }
        }
        
        static void Main()
        {
            try
            {
                string s = null;
                ProcessString(s);
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception caught.", e);
            }
        }
    }示例输出
    System.ArgumentNullException: Value cannot be null.
       at MainClass.Main() Exception caught.
    此例使用了两个 catch 语句。最先出现的最特定的异常被捕获。// try_catch_ordering_catch_clauses.cs
    using System;
    class MainClass
    {
        static void ProcessString(string s)
        {
            if (s == null)
            {
                throw new ArgumentNullException();
            }
        }    static void Main()
        {
            try
            {
                string s = null;
                ProcessString(s);
            }
            // Most specific:
            catch (ArgumentNullException e)
            {
                Console.WriteLine("{0} First exception caught.", e);
            }
            // Least specific:
            catch (Exception e)
            {
                Console.WriteLine("{0} Second exception caught.", e);
            }
        }
    }
    示例输出
    System.ArgumentNullException: Value cannot be null.
       at MainClass.Main() First exception caught.注释
    --------------------------------------------------------------------------------在前面的示例中,如果从具体程度最低的 catch 子句开始,您将收到以下错误信息:A previous catch clause already catches all exceptions of this or a super type ('System.Exception')。但是,若要捕获特定程度最小的异常,请使用下面的语句替换 throw 语句:throw new Exception();
      

  6.   

    肯定要 捕获,推荐 多使用  try  catch, 万一 程序错误,程序可能 崩溃,停止运行,又不知道哪 出错了,抛出异常,即可解决。
      

  7.   

    有些地方报的错误可以忽略的时候就可以用try catch
      

  8.   


    异常不是程序中必须的,c中的错误通知是通过返回值和SetLastError。对操作系统而言,是不存在异常这个东西的。异常都是各种语言自己独立一套的。比如你看到c++/java/.net呈现的异常方式都是不同的。关于异常,看看这个博客中的文章1.从零开始学习异常.了解与入门
    http://www.cnblogs.com/dawave/archive/2008/07/14/1242134.html
    2.更深入了解异常机制,和它的意义. 
    http://www.cnblogs.com/anderslly/archive/2007/03/14/understandingexception1.html
    3.Enterprise架构中, 及其中异常处理. 是一个很不错的方案.
    http://www.cnblogs.com/jiangshaofen/archive/2007/12/11/990953.html 
    4.Microsoft官方异常设计准则
    http://msdn.microsoft.com/zh-cn/library/ms229014.aspx
    5.<.net设计规范>第七章 - 人民邮电出版社 49$
    http://www.cnblogs.com/anderslly/archive/2007/03/15/675642.html
      

  9.   

    try catch
    就是可能会出错的代码块用这个包起来,
    这样就能抛出异常,可以检查代码,一般的书籍都有介绍的,这个功能挺长的,
    LZ最好可以去找本书籍看看.
      

  10.   

    主要想澄清几点:
    CPU支持异常。
    操作系统支持异常。
      

  11.   

    try中放可能发生错误的代码块,catch中可以捕获错误信息
      

  12.   

    er...
    cpu有异常处理的中断、操作系统有seh机制。我上面直接说没有的的确不合适。
    应该说.net/java/c++中所说的异常都是基于运行库的,比如IndexOutOfRangeException,只是针对.net clr中访问越界的检查,与操作系统的,cpu的不是同一个东西。不过这跑题了。
      

  13.   

    而且,微软c++等的异常实现是基于SEH的。
      

  14.   

    当然try,catch不仅限定于用户界面层,但是对于分层的应用程序来说。各个层次处理不同的Exception。比如 DAO层可以定义SqlException,BLL层可以定义LogicException, 画面层可以定义UIException
    Exception是父类,自定义的Exception通常继承于ApplicationException对于分层的应用程序,各层捕获到跟自己负责的Exception后进行包装。
    比如用OleDb访问DB,哪么DAO层应该捕获OleDbException做一些特定DAO层应该处理的事。类似下面的代码//DAO层
    try
    {
       ...
    }
    catch(OleDbException dbErr)
    {
        // 这里包装了OleDbException,还加上自定义的消息。
        throw new SqlException(dbErr, "DAO层自定义的Message");
    }
    // 注意这里只Catch了OleDbException,其他Exception直接往上抛。通过这样有规则的包装,在出现问题的时候,通过自定义消息的提示,你可以更加明确
    轻松的找到问题所在。还可以通过自定义的消息,跟最终的用户更加友好的提示。
    你不会想让用户看到什么 null reference 这样的消息吧。
    这些都是在你的catch中所做的事:1.包装Exception;2.把Exception的内容及发生错误的位置(StackTrace)写到你的日志中;3.自定义错误信息,给客户友好的提示。
    我提到在UI层做try,catch,因为这是最低要求。
    因为程序一层一层调用,简单来说不用所有的方法都加上try,catch
    也不要在所有的方法里都加上 MessageBox.Show(ex.Message) 这样看上去很乱不是吗?
    换句话说:我们应该在编码上有统一的风格。个人认为简单的应用,可以按照以下原则追加Try,Catch
    1. 所有的UI事件中。因为对于事件驱动的应用中,UI事件的处理方法都是最外层的方法。
       是捕获异常的最后一关。
       比如:Form_Load, Button_Click, ...
    2. 所有ThreadStart所指向的方法。对于多线程来说,子线程的主方法是应该做错误处理的。
    3. Cosole程序的Main方法。...待续
      

  15.   

    接下来,还有个Try Catch + Throw Exception的应用场景。有一个Form,上面几十个输入框(TextBox),每个输入框的类型都不同。
    在某个button按下的时候,需要做一个输入检查。常见的代码:if ( string.IsNullOrEmpty(txtUserName.Text) )
    {
       MessageBox.Show("请输入用户名。");
       txtUserName.Focus();
       return;
    }if ( ! IsNumber(txtXXX1.Text) )
    {
       ...
    }if ( ! IsEmail(txtXXX2.Text) )
    {
       ...
    }
    总之,这样If判断,然后MessageBox.Show(...), Focus()的代码重复出现。
    突然有会,离开下。
      

  16.   

    LZ啊 你如果一下子不知道或者还不了解为什么的话!你只要记住,在可能或者肯定会出现错误信息,以及你担心会出现状况的位置加上TRY CATCH FINALLY  这个东东 是不会错的.
      

  17.   

    这种分散在各个button里的if判断和MessageBox处理,可以统一的抽象出来。做成一个个内部的Validate方法,然后自定义InputCheckException,形如:
     public partial class Form1 : Form
        {
            private Dictionary<string, string> messagePool = new Dictionary<string, string>();        public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                // Message可以统一放到Resource里。
                messagePool.Add("E0001", "请输入用户名。");
                messagePool.Add("E0002", "请输入密码。");
            }        private void ValidateNullEmptyInput(Control control)
            {
                if (string.IsNullOrEmpty(control.Text))
                    throw new InputCheckException(control.Name, "E0001");
            }        private void HandlerInputException(InputCheckException inputEx)
            {
                MessageBox.Show(messagePool[inputEx.MessageID]);
                Control[] controls = this.Controls.Find(inputEx.ControlName, true);
                if (controls != null && controls.Length > 0)
                    controls[0].Focus();
            }        private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    // 输入验证
                    ValidateNullEmptyInput(this.textBox1);
                    
                    // 调用某业务逻辑
                    // logicXXX.Execute(...);            }
                catch (InputCheckException inputEx)
                {
                    // 处理验证错误
                    HandlerInputException(inputEx);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("未知的错误:" + ex.Message);
                    // Log错误堆栈
                    Trace.WriteLine(ex.StackTrace);
                }
            }
        }    public class InputCheckException : ApplicationException
        {
            public string ControlName
            { get; private set; }        public string MessageID
            { get; private set; }        public InputCheckException(string controlName, string messageID)
            {
                ControlName = controlName;
                MessageID = messageID;
            }
    这样整个代码的结构,看上去就更加合理,也容易维护了。
      

  18.   

    1,Try{
       ...
      }Catch(Exception e){
        ...
      }2,你执行上面第一个大括号里的代码如果出现运行时异常,就会跳到第二个大括号里执行,这叫做“异常处理”。
    大部分现代程序设计语言都有这个功能。3,可以这么理解。你在操作用户界面时可能不希望程序出错立刻崩溃退出,而是希望最差是某个按钮没反应了,这样别的按钮可以点。4,不是“Log错误”,而是“不能-Log-错误堆栈”,“Log"是动词,动宾结构,记录下来的“错误堆栈”可以用来跟踪错误的原因。
      

  19.   

    UI 层主要是负责界面相关操作的(User Interface)
      

  20.   

    简单的说try catch 就是用来容错的
      

  21.   

    try catch
    就是可能会出错的代码块用这个包起来,
    这样就能抛出异常,可以检查代码
      

  22.   

    去了解一下什么是 Application 的ThreadException事件即可。
      

  23.   

    代码都写上try{}catch()finally{}
      

  24.   

    之前在CE5.0环境下写程序,
    因为没有用TRY CATCH,
    碰到异常就把系统给弄死掉了,
    扣电池重新启动....