C# 不可预见异常的处理
如果我想写入文件并处理C# 不可预见异常的处理,c#,exception,try-catch,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);
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;
}
这会有什么不同吗?最佳做法是什么?您好,如果您想引发应用程序将崩溃的异常,请执行此操作
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);
}
}
然后处理对象
未测试您可以捕获异常,然后在内部检查ExpException的类型。然后决定如何处理它
catch(Exception ex)
{
if(ex.InnerException is IOException )
{
// do something
}
else
{
// do something else
}
}
您可以使用该事件
也许你也想参加这个活动
那么,我应该添加另一个类似的捕获吗
(几乎)从来没有。至少不在堆栈跟踪中。这只会让你的申请更难阅读
大多数应用程序都有入口点。例如,如果您正在编写windows服务,则通常会为该工作创建线程。您可以在它们中设置一个catch(Exception)
,以防止它们崩溃
所以我想说的是,在大多数情况下,您应该只在顶层使用catch all,以防止您的应用程序更难阅读或维护
当一切都失败时
有时,如果您忘记了顶层的某个地方,您的应用程序无论如何都会崩溃
然后,您希望在.NET中为所有应用程序类型调用时使用AppDomain.UnhandledException
。但是,它不允许您阻止应用程序崩溃,只允许您记录应用程序即将崩溃的原因
如果您正在基于winforms编写UI应用程序,则可以使用应用程序.ThreadException
。但是,它将只处理UI线程上的异常。因此,您仍然需要使用AppDomain.UnhandledException
来记录在其他线程上引发的异常
NET中所有主要的库/框架都有自己的方式来允许您处理未处理的异常。您需要在正在使用的库的文档中查找它
catch(Exception)
{
throw;
}
什么也不做。异常将与其原始堆栈跟踪一起引发,并且不会执行其他操作。您可以捕获一般异常,这使您可以选择提供额外的日志记录和/或向用户显示更好的错误消息
catch(Exception ex)
{
LogError(ex);
if (weDontCareThisWasntImportantAnyWay)
{
if (theUserShouldBeNotifiedAtThisPoint)
{
SomehowNotifyTheUser(ex);
}
}
else
{
//Maybe something else cares
throw;
}
}
您应该处理意外的异常,但是带有
throw
的catch
是多余的-无论如何,异常都会从您的方法中抛出。你应该做的是问自己这样一个问题,“我能为这个例外做些什么?”。对于IOException
,答案很清楚。您期望异常可能发生,可以处理它,并且可以继续。对于一般的异常
,这里可能不是处理它的地方
catch(Exception ex)
{
if(ex.InnerException is IOException )
{
// do something
}
else
{
// do something else
}
}
如果发生异常时需要运行某些代码,请为其添加一个catch
。如果代码在该异常后无法继续,请将异常抛出更高级别(通过不处理它或使用抛出
),并在调用层次结构中向上添加处理程序。也许它可以在更高的层次上处理,并且可以继续执行。否则,您的应用程序将需要退出
您可以在程序的入口点添加顶级try
/catch
块,并在那里捕获未处理的异常。在此之后,您的应用程序甚至可以继续运行(但是,考虑到此时抛出的异常有多高,在任何非平凡的应用程序中都不太可能)。要捕获任何其他未处理的异常(例如,在线程中未处理的异常),可以将处理程序添加到。但是,这是不可恢复的-您的应用程序将在之后直接退出。UnhandledException
处理程序是在异常发生之前对异常执行操作的最后一次机会,通常会记录异常以诊断出错的原因
哦,另外,如果您正在编写WPF应用程序,您可以在App.xaml中为
application
上的事件添加一个处理程序。捕获WPF调度程序线程中发生的任何未处理的异常。与上面的AppDomain
处理程序不同,dispatcher线程上未处理的异常可以从继续-如果应用程序可以继续,则可以在事件参数中将IsHandled
设置为true
。我不希望应用程序在IOException上崩溃,因为我不希望应用程序在IOException上崩溃,除非它可能发生并因此处理它。这是关于我不排除的例外情况。我应该捕获它们并抛出还是什么都不做。因此,在异常中返回消息并显示给用户,然后编写带有错误的自定义日志(return ex.message;)这会重置堆栈跟踪为什么?您可以捕获(IOException),然后通过链接处理程序回退到Exception()。@kha:您没有注意到他检查了内部异常吗。您无法捕获它。@jgauffin问题是关于捕获IOException和调用方法时可能发生的其他类型的异常,这个答案是检查捕获所有异常的内部异常作为一种方法。这种方法是错误的:不是每个异常都有InnerException,也不是每个IOException都被重新抛出(事实上,如果重新抛出IOException是标准行为,我会感到惊讶)这意味着此解决方案不会处理导致异常的IOException,也不会将其作为另一种类型的异常与IOException对象的InnerException一起重新抛出。您也可以使用我们的服务,它为您处理所有集成。