Pergunta

Under certain circumstances, I get an NRE when closing a form using its Close button, which simply calls the native (WinForms) Close() method.

Certain paths through the code do fine, but one particular path causes the Null Reference Exception. Since this is nominally a scenario where something that is null is being referenced, how could this be taking place when the form is simply being closed? I can imagine there being a memory leak, perhaps, but something null being referenced I'm not understanding.

What potential causes in the code might there be?

UPDATE

Answer to Jon Skeet:

I'm unable to debug this in the normal way for reasons boring and laborious to relate (again), but what I can do is this:

catch (Exception ex)
{
    MessageBox.Show(ex.Message);
    MessageBox.Show(ex.InnerException.ToString());
    SSCS.ExceptionHandler(ex, "frmEntry.saveDSD");
}

The last is an internal/custom exception processing method.

All I get from these lines is:

"Null Reference Exception"
Nothing (empty string)
"Exception: NullReferenceException Location: frmEntry.btnSave.click

Note that the last exception shown now implicates btnSave.click as the culprit, whereas it formerly pointed the finger at saveDSD. Curiouser and curiouser. Is this a case of the Hawthorne Effect* in action (well, a modified Hawthorne Effect, in the sense that adding this debugging code might be changing things).

  • The canonical Hawthorne Effect being more like this sort of scenario: A bunch of cats are playing basketball. Some girls walk up and watch. The cats start showing off and hotdogging, and one breaks his leg. Is it the girls' fault? No. Would it have happened had they not been watching? No.

UPDATE 2

Talk about the Hawthorne Effect: When I copied the two MessageBox.Show() calls to the catch block of frmEntry.btnSave.click, I then got:

"Null Reference Exception"
"Null Reference Exception"
"Exception: NullReferenceException Location: frmEntry.Closing"

IOW, the location of the NRE keeps moving about, like a squirrel on a country road when [h,sh]e meets two cars going opposite directions.

UPDATE 3

And it happened once more: adding those MessageBox.Show()s to the form's Closing event causes the NRE to pop up out of a different hole and declare itself. This inbred code is begetting (or cloning) half-wits by the score, or so it seems.

UPDATE 4

If writing bad code were a crime, the cat who wrote this stuff should be in solitary confinement in a SuperMax.

Here's the latest egregious headscratcher/howler:

int cancelled = ListRecords.cancelled;
if (cancelled == 0)
. . .

The public "cancelled" member of ListRecords (in another class) is only ever assigned values of 0 and 1. Thus, not only does cancelled sound like a bool, it acts like a bool, too. Why was it not declared as a bool?!?!?

The official image of this codebase should be Edvard Munch's "The Scream"

UPDATE 5

Maybe I'm venting, but recent experiences have caused me to come up with a new name for certain types of code, and an illustration for many projects. Code that doesn't go anywhere, but simply takes up space (assignments made, but are then not acted on, or empty methods/handlers called) I now call "Winchester Mystery House code."

And for the typical project (I've been a "captured" employee as well as a contractor on many projects now, having almost 20 years experience in programming), I now liken the situation to a group of people wallowing in quicksand. When they hire new people to "come aboard," they really want them to jump into the quicksand with them. How is this going to help matters? Is it just a case of "misery loves company"? What they should be doing is saying "Throw us a rope!" not "Come on in, the quicksand is fine!"

Many times it's probably just entropy and "job security" at play; if they keep wrestling with the monstrosity they've chosen or created, their hard-won knowledge in how to keep the beast more-or-less at bay will keep them in their semi-comfy job. If they make any radical changes (most teams do need to make some radical improvements, IMO), this may endanger their employment status. Maybe the answer is to employ/contract "transition teams" to move teams/companies from prehistoric dinosaur-clubbing times into the 21st Century, training the "old guard" so that they can preserve their jobs. After all, there aren't enough of these "saviors" to steal the old hands' jobs anyway - train them up, get them up to speed, and move on. All would benefit. But many seemingly prefer to continue wallowing in the mire, or quicksand.

Before anybody hires a programmer, they should give them at the minimum a test wherein passing the test would prove that they are at least familiar with the basic tenets delineated in Steve McConnell's "Code Complete."

Okay, back to battling the quicksand...

UPDATE 6

Or: "Refactoring Spo-dee-o-dee":

A "gotcha" with refactoring is if you change the name of a variable such as this:

ChangeListType chgLst; // ChangeListType is an enum

...to this:

ChangeListType changeListType;

...and if there is a data table with a column named "chgLst", SQL statements can also get changed, which can ruin, if not your day, at least part of it.

Another potential gotcha is when you get, "[var name] is only assigned but its value is never used" hints. You may think you can just cavalierly 86 all of these, but beware that any related code which you may comment out along with assignments to these dead vars is not producing relied-upon side effects. Admittedly, this would be a bad way to code (side effectual methods storing their return vals in vars that are ignored), but ... it happens, especially when the original coder was a propeller-head mad scientist cowboy.

This code is so chock full of anti-patterns that I wouldn't be surprised if Butterick and/or Simplicity put out a contract on this guy.

On second thought, aside from the architecture, design, coding, and formatting of this project, it's not really all that bad...

Mary Shelley's "Frankenstein" was very prescient indeed, but not in the way most people have thought. Rather than a general foreboding about technology run amok, it is much more specific than that: it is a foregleam of most modern software projects, where "pieces parts" from here and there are jammed together willy-nilly with little regard to whether "the hip bone's connected to the thigh bone" (or should be) and whether those parts match up or will reject one another; the left hand doesn't know what the right is doing, and devil take the hindmost! Etc.

Foi útil?

Solução

That can happen under any of these situations:

  • object obj is null and your code has obj.ToString()
  • string item is null and your code has item.Trim()
  • Settings mySettings is null and your code has mySettings.Path

Less common things would be a thread running that posts information or a serial port that tries to receive data after the SerialDataReceivedEventHandler has been removed.

Look at what your suspect form's code and the parent form's code are doing about the time this suspect form is closed and what other processes might be running on the suspect form.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top