在这里通过更聪明的头脑温和地惩罚我,我将我的调用切换到MessageBox.Show(),以便将行写入StringBuilder,后者将从应用程序的自定义异常处理程序保存到文件中:
public static void ExceptionHandler(Exception ex, string location)
{
try
{
if (inDebugMode)
{
LogMsgs.Append(string.Format("{0}\r\n", ex.Message));
DateTime dt = DateTime.Now;
string timeAsStr = string.Format("{0}_{1}_{2}_{3}.txt", dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
using (StreamWriter file = new StreamWriter(timeAsStr))
{
// If the app crashes, this is how the file is written; if it doesn't, it's written
// in frmCentral.Form1_Closing()
file.WriteLine(LogMsgs.ToString());
}
}
MessageBox.Show("Exception: " + ex.Message + "\n\nLocation: " + location, GetFormTitle("CCR: " + ex.GetType().FullName,"",""));
}
(......这就像这样:
catch (Exception ex )
{
CCR.ExceptionHandler(ex, "WriteXML.WriteFile");
. . .
) ...并从主窗体的Closed()事件:
private void frmCentral_Closed(object sender, EventArgs e)
{
if (CCR.inDebugMode)
{
DateTime dt = DateTime.Now;
string timeAsStr = string.Format("{0}_{1}_{2}_{3}.txt", dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
using (StreamWriter file = new StreamWriter(timeAsStr))
{
// If the app closes normally, this is how the file is written; if it doesn't,
// (it crashed) it's written in PDAClient.ExceptionHandler()
file.WriteLine(CCR.LogMsgs.ToString());
}
}
} // frmCentral_Closed
直到今天早些时候才开始使用。我对该代码没有任何改动。但是现在,无论代码是否崩溃(我能够从主窗体中关闭它),文件都没有写入(至少不是以前写过的地方,即手持设备的根目录)。
我正在添加类似的消息:
CCR.LogMsgs.Append(string.Format("DBCommand exception: {0}\r\n", ex.Message));
..并且inDebugMode布尔值确实被设置为true而无处可能:
public static bool inDebugMode = true; //TODO: Change this to false before deploying.
什么可能导致这种恶意遗漏?
回答jp2code:
这就是ExceptionHandler在catch块中的作用:
catch(Exception exc)
{
MessageBox.Show("Exception Handler generated an exception!\n" + exc.Message + "\n\nCalling Location: " + location, GetFormTitle("CCR: " + exc.GetType().FullName,"",""));
}
请注意,我没有编写此代码,因此我经常(通常?)不知道其背后的动机或心态。它看起来比Italienfest更加惹人注目,但也许我只是不喜欢它。
很多东西不是它们出现在代码中的东西,例如,void函数被命名为bool函数,而这个ExceptionHandler()方法你会想到(我会,无论如何),它是一个全局的/ catch-all异常处理程序,但实际上必须从整个代码中的catch块显式调用才能执行。
另外:我试图实现errHndlrLock代码,但得到编译错误的msg,“非静态字段,方法或属性'PDAClient.SSCS.errHndlrLock'”<需要对象引用/ p>
今天又恢复了工作;一定是一个记忆问题或类似的东西 - 虽然我昨天没有喘息的机会进行了热烈的启动。所以:它起作用了,它突然无法工作,就像突然(一夜之间)一样,它又开始起作用了。
我认为这是在令人难以置信的神秘消失的调试日志文本文件的情况下发生的事情的线索。当我今天打开最新的那些时,它们充满了:
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
......那些足够的,整个shebang决定去度假,我想。但现在,它再次处于中断状态 - 这个CE爵士乐比我祖母的馅饼皮更加绚丽。
答案 0 :(得分:2)
我可能错了,但看起来你的流缓冲区没有被刷新。
尝试添加
file.Flush();
在你打电话给writeline之后。此外,我没有看到您明确关闭流的地方。这样做是很好的做法。
答案 1 :(得分:2)
Nat可以通过Flush
来电话。我给了他一个+1。
可能发生的另一件事(我遇到过)是一次尝试访问您的异常处理程序的多个项目。
假设您正在关闭表单,并且您的某个方法中存在异常。现在你有两(2)个例程试图一次访问你的timeAsStr
文件,这是不可能发生的。
解决方法是在您的异常处理程序例程中添加lock
:
private object errHndlrLock = new Object();
public void ExceptionHandler(Exception ex, string location) {
lock (errHndlrLock) {
// continue with your code
}
}
我想到的另一件事是:我看到你的异常处理程序代码显示了try/catch
块的一部分。
问。您如何处理您遇到的例外情况?
如果您以递归方式调用相同的方法,则可能导致您丢失信息。
如果您想采用不同的方法,可以使用Queue
,定义全局到该类,以及StreamWriter
:
class CCR {
private Queue<string> m_queue;
private StreamWriter m_writer;
public CCR() {
m_queue = new Queue<string>();
m_writer = new StreamWriter(string.Format("Log_{0}.txt", DateTime.Now.ToFileTime()));
}
public void ExceptionHandler(Exception ex, string location) {
string item = string.Format("{0:u}: {1}\r\n\t\t{2}", DateTime.Now, location, ex.Message);
if (ex.InnerException == null) {
m_queue.Enqueue(item);
} else {
m_queue.Enqueue(item + string.Format("\r\n\t\tInner Exception: {0}", ex.InnerException.Message));
}
QueueHandler();
}
private void QueueHandler() {
while (0 < m_queue.Count) {
m_writer.WriteLine(m_queue.Dequeue());
}
}
public void Close() {
QueueHandler();
m_writer.Flush();
m_writer.Close();
m_writer.Dispose();
}
请确保在代码退出之前致电Close()