How could the existence of pseudo debug strings ca

2019-08-24 22:48发布

问题:

If I have these sprinkled throughout my code:

MessageBox.Show("See a format exception yet? #1");//todo: remove

(there are 7 of these, numbered from 1..7, most of which display (1,2,5,6,7))

I end up with one err msg ("Exception: Cannot find table 0 Location: frmFunction.SetPlatypus")

If I comment out all of those, I end up with a different err msg ("Exception: FormatException Location frmFunction.getDuckbillRecord")

How could this be? Shouldn't the existence/display of such an information msg have no effect on the way the code executes/the path it takes, etc.?

Note: getDuckbillRecord() is where all of the MessageBoxes are.

UPDATE

Using RT's suggestions as motivation, I came up with this:

public static StringBuilder LogMsgs = new StringBuilder();

    public static void ExceptionHandler(Exception ex, string location)
    {
        try
        {
            LogMsgs.Append(string.Format("{0}\r\n", ex.Message)); //TODO: Comment out before deploying?
            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))
            {
                file.WriteLine(LogMsgs.ToString());
            }
            . . .

//in the problematic code, replacing the MessageBox.Show() calls:

    TTBT.LogMsgs.Append("Made it to location 1 in frmOverFunction.GetDuckbillRecord()\r\n");

...and it did help - the exception is reached right after the first of 7 "code waypoints," so there's something rotten in that particular Denmark, apparently.

UPDATE 2

After the rare experience of being able to run the app without crashing somewhere, I realized I also need that file-writing code in the main form's OnClosing() event - being in the global exception handler had worked for awhile - I wasn't expecting a clean termination of the app to ever occur again, I guess.

回答1:

I'd strongly encourage you NOT to use MessageBox.Show(...) to log/trace/debug errors, because popping-up a dialog can introduce many subtle bugs and changes in behavior, focus, etc., especially if your UI flow/state is important.

Instead, use System.Diagnostics.Trace for writing tracing code (which you can optionally compile into your production/release code) or System.Diagnostics.Debug to write debug messages which get removed when you build your release version.

For example:

public void DoSomething(int a, int b)
{
    Trace.TraceInformation("Starting to do something: a = {0}, b = {1}",
        a, b);

    try 
    {
        int c = a / b;
    }
    catch (DivideByZeroException e)
    {
        Debug.WriteLine("OH NO ... 'b' WAS ZERO!!!! RUN AWAY!!!!");
        throw e;
    }

    Trace.TraceInformation("Done doing something");
}

In the example above, the debug output will be available in debug builds, but will be removed in release builds. Trace output will be available in debug and retail bugs (unless you turn off the TRACE build parameter) but introduces no measurable perf impact unless you hook-up a listener and start writing trace output to a slow medium like spinning disks, ticker-tape printers, etc. ;)

When you run code with Trace and/or Debug builds with Debug messages in Visual Studio, the messages are written to the Output pane so you can watch what's going on inside your app as it runs.

If you want to, you can also write a stand-alone trace listener that listens for Trace and/or Debug messages and log them to a file/database or display them in a console window (or GUI if you want to get fancy).

You can also use tools like log4net which enables you to write log/trace messages to a variety of file formats, databases, etc.