处理不可预见的例外情况

时间:2015-03-25 10:32:15

标签: c# exception try-catch

如果我想写入文件并处理IOExceptions(如果文件被写保护),我会执行以下操作:

try
{
    var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)
    {    
        sw.WriteLine(entry);
    }
}
catch (IOException ex)
{
    return ex.Message;
}

如果我收到意外的异常,我的程序将崩溃,用户将报告错误,我将修复它。这就是我想要的。

所以我应该添加另一个像:

catch (Exception)
{
    throw;
}

这会有什么不同,最佳做法是什么?

6 个答案:

答案 0 :(得分:3)

您应该处理意外的异常,但catch的{​​{1}}是多余的 - 无论如何都会抛出异常。你应该做的是问问自己这个问题,"我在这里可以做些什么呢?"。对于throw,答案很清楚。您希望可能发生异常,可以处理它,并且可以继续。在通用IOException的情况下,这可能不是处理它的地方。

如果您在发生异常时需要运行某些代码,请为其添加Exception。如果您的代码在该异常之后无法继续,请将异常提高(通过不处理或使用catch),并在调用层次结构中添加更高的处理程序。也许它可以在更高的层次上处理,并且可以继续执行。如果没有,您的申请将需要退出。

您可以在程序的入口点添加顶级throw / try块,并在那里捕获未处理的异常。您的应用程序甚至可以在此之后继续(但是,在任何非平凡的应用程序中它都不太可能,因为此时将抛出异常的高度)。要捕获任何其他未处理的异常(例如,在线程中未处理的异常),您可以向AppDomain.CurrentDomain.UnhandledException添加处理程序。但是,这是不可恢复的 - 您的应用程序将在之后直接退出。 catch处理程序是在此之前对异常执行某些操作的最后机会,通常记录它以诊断出错的地方。

哦,另外,如果您正在编写WPF应用程序,则可以在App.xaml中为UnhandledException上的DispatcherUnhandledException事件添加处理程序。捕获WPF调度程序线程中发生的任何未处理的异常。与上面的Application处理程序不同,调度程序线程上的未处理异常可以继续 - 如果对于应用程序来说可以将事件args中的AppDomain设置为IsHandled继续。

答案 1 :(得分:1)

  

所以我应该添加另一个像

这样的捕捉

(差不多)从不。至少不在堆栈跟踪中。它只会让你的应用程序更难阅读。

大多数应用程序都有入口点。例如,如果您编写Windows服务,通常会为工作创建线程。您可以在其中catch (Exception)以防止它们崩溃。

所以我所说的是,在大多数情况下,您应该只在顶层使用catch,以防止您的应用程序难以阅读或维护。

当一切都失败时

如果你忘记了顶层的某个地方,你的应用程序有时会崩溃。

然后,您希望在.NET中为所有应用程序类型调用AppDomain.UnhandledException。但是,它不会让您阻止应用程序崩溃,而只是记录您的应用程序即将崩溃的原因。

如果您正在基于winforms编写UI应用程序,则可以使用Application.ThreadException代替。但是,它只会处理UI线程上的异常。因此,您仍然需要使用AppDomain.UnhandledException来记录在其他线程上抛出的异常。

.NET中的所有主要库/框架都有自己的方式来允许您处理未处理的异常。您需要在您正在使用的库的文档中查找它。

答案 2 :(得分:0)

嗨如果您想抛出应用程序崩溃的异常,请执行此操作

 try
{
    var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)
    {    
        sw.WriteLine(entry);
    }
}
catch (IOException ex)
{
    throw ex;
}

但在我看来你不应该让它粉碎但只显示错误信息

在catch调用函数中写入文件,然后返回消息并显示给用户。希望它有所帮助

 public static void WriteCustomLog(string msg)
            {
                FileStream fs = null;
                StreamWriter sw = null;
                FileStream fs1 = null;
                StreamWriter sw1 = null;
                try
                {
                    //check and make the directory if necessary; this is set to look in the application
                    //folder, you may wish to place the error log in another location depending upon the
                    //the user's role and write access to different areas of the file system
                    if (!System.IO.Directory.Exists(Application.StartupPath + "\\Log\\"))
                        System.IO.Directory.CreateDirectory(Application.StartupPath + "\\Log\\");

                    string date = DateTime.Now.ToString("dd_MM_yyyy");

                    //check the file
                    fs = new FileStream(Application.StartupPath + "\\Log\\Log" + date + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    sw = new StreamWriter(fs);
                    sw.Close();
                    fs.Close();

                    //log it
                    fs1 = new FileStream(Application.StartupPath + "\\Log\\Log" + date + ".txt", FileMode.Append, FileAccess.Write);
                    sw1 = new StreamWriter(fs1);
                    sw1.Write(DateTime.Now.ToString() + " Message: " + msg + Environment.NewLine);
                    sw1.Write("Date/Time: " + DateTime.Now.ToString() + Environment.NewLine);
                    sw1.Write("=======================================================" + Environment.NewLine);

                }
}

然后处理对象 未经测试

答案 3 :(得分:0)

您可以使用AppDomain.UnhandledException事件。

也许您也想使用Application.ThreadException事件。

答案 4 :(得分:0)

catch(Exception)
{ 

    throw;    
} 

什么都不做。使用它的原始堆栈跟踪抛出异常,并且不执行其他操作。您可以捕获一般异常,这使您可以选择提供其他日志记录和/或向用户显示更好的错误消息

catch(Exception ex)
{ 
    LogError(ex);
    if (weDontCareThisWasntImportantAnyWay)
    {
        if (theUserShouldBeNotifiedAtThisPoint)
        {
            SomehowNotifyTheUser(ex);
        }
    }
    else
    {
        //Maybe something else cares
        throw;    
    }
} 

答案 5 :(得分:-1)

您可以捕获异常,然后在内部检查异常的类型。然后决定如何处理它。

catch(Exception ex)
{
  if(ex.InnerException is IOException )
  {
    // do  something
  }
 else
  {
   // do something else
  }
}