Newbie Question: Invoke and NullReferenceException

D

Derrick Tan

Hi There!

I'm working on my first app in C# and I have a slight problem which is
somewhat inconsistent.

Here's the code:

===============================================================

public delegate void BoolEventHandler( bool boolean );

public void ResignReply( bool clientAgreed )
{
if (this.InvokeRequired)
{
BoolEventHandler bHandler = new BoolEventHandler( this.ResignReply );
this.Invoke( bHandler, new object[] { clientAgreed } );
return;
}

// Code that changes controls in the main window form.
//

}

===============================================================

Basically I'm calling this method from a thread that has not created the
controls I want to change, so I have to call Invoke. The problem is I
sometimes get a NullReferenceException on the line with:

this.Invoke( . . . );

An unhandled exception of type 'System.NullReferenceException' occurred
in system.windows.forms.dll

Additional information: Object reference not set to an instance of an
object.

Call Stack:

system.windows.forms.dll!System.Windows.Forms.Control::MarshaledInvoke(System.Windows.Forms.Control
caller = {Backgammon.BackgammonForm}, System.Delegate method =
{Backgammon.BoolEventHandler}, System.Object[] args = {Length=1}, bool
synchronous = true) + 0x330 bytes


system.windows.forms.dll!System.Windows.Forms.Control::Invoke(System.Delegate
method = {Backgammon.BoolEventHandler}, System.Object[] args =
{Length=1}) + 0x30 bytes

Backgammon.exe!Backgammon.BackgammonForm.ResignReply(bool clientAgreed =
true) Line 1442 + 0xe bytes


I was hoping someone could explain to me why this is happening. On a
side note, I have almost identical code for a different method which
doesn't seem to throw the exception. . .

If you need more information, please let me know. . .

Many Thanks,

Derrick
 
W

William Ryan

Threading is not for the meek of heart...not to say that you are by any
means. I'll ask that you post the code that calls the threads, b/c there
can be a lot going on, although that exception message is a pretty good
indicator or the problem. Intuitively, NullReference exceptions occur
pretty predictably. Remember that in a threaded app, movement isn't linear.
Also remember that forms aren't thread safe, so you can't count on their
'state' being correct.

My guess is that if you throw a few Debug.Assert(myObject != null) in front
of your methods..you will probably find out the problem. You can't count on
the debugger (well, that depends on the code, but essentially I'm right
about this).

If you would, post the code, it'll be easier to figure out.. but try a bunch
of assertions first.... they are the best tip off to a problem...

my favorite is

try{
}

catch(whateverexception ex){

Debug.Assert(false, ex. ToString());
}
Derrick Tan said:
Hi There!

I'm working on my first app in C# and I have a slight problem which is
somewhat inconsistent.

Here's the code:

===============================================================

public delegate void BoolEventHandler( bool boolean );

public void ResignReply( bool clientAgreed )
{
if (this.InvokeRequired)
{
BoolEventHandler bHandler = new BoolEventHandler( this.ResignReply );
this.Invoke( bHandler, new object[] { clientAgreed } );
return;
}

// Code that changes controls in the main window form.
//

}

===============================================================

Basically I'm calling this method from a thread that has not created the
controls I want to change, so I have to call Invoke. The problem is I
sometimes get a NullReferenceException on the line with:

this.Invoke( . . . );

An unhandled exception of type 'System.NullReferenceException' occurred
in system.windows.forms.dll

Additional information: Object reference not set to an instance of an
object.

Call Stack:

system.windows.forms.dll!System.Windows.Forms.Control::MarshaledInvoke(Syste
m.Windows.Forms.Control
caller = {Backgammon.BackgammonForm}, System.Delegate method =
{Backgammon.BoolEventHandler}, System.Object[] args = {Length=1}, bool
synchronous = true) + 0x330 bytes


system.windows.forms.dll!System.Windows.Forms.Control::Invoke(System.Delegat
e
method = {Backgammon.BoolEventHandler}, System.Object[] args =
{Length=1}) + 0x30 bytes

Backgammon.exe!Backgammon.BackgammonForm.ResignReply(bool clientAgreed =
true) Line 1442 + 0xe bytes


I was hoping someone could explain to me why this is happening. On a
side note, I have almost identical code for a different method which
doesn't seem to throw the exception. . .

If you need more information, please let me know. . .

Many Thanks,

Derrick
 
D

Derrick

Hi William,

Thanks for the quick reply =D

There actually isn't any other real code to post. A delegate of type
BoolEventHandler is called with true.

[recall that my BoolEventHandler delegate is declared as:
public delegate void BoolEventHandler( bool boolean );]

The frustrating thing is that I changed the code to the following and I
cannot seem to replicate the error anymore:

==================================================================
try
{
this.Invoke( bHandler, new object[] { clientAgreed } );
}
catch( NullReferenceException e )
{
Debug.Assert( false, e.ToString() );
}
=================================================================

That is, all I did was enclose the problem line with a try-catch and it
is no longer causing any problems. . .

dtan

William said:
Threading is not for the meek of heart...not to say that you are by any
means. I'll ask that you post the code that calls the threads, b/c there
can be a lot going on, although that exception message is a pretty good
indicator or the problem. Intuitively, NullReference exceptions occur
pretty predictably. Remember that in a threaded app, movement isn't linear.
Also remember that forms aren't thread safe, so you can't count on their
'state' being correct.

My guess is that if you throw a few Debug.Assert(myObject != null) in front
of your methods..you will probably find out the problem. You can't count on
the debugger (well, that depends on the code, but essentially I'm right
about this).

If you would, post the code, it'll be easier to figure out.. but try a bunch
of assertions first.... they are the best tip off to a problem...

my favorite is

try{
}

catch(whateverexception ex){

Debug.Assert(false, ex. ToString());
}
Hi There!

I'm working on my first app in C# and I have a slight problem which is
somewhat inconsistent.

Here's the code:

===============================================================

public delegate void BoolEventHandler( bool boolean );

public void ResignReply( bool clientAgreed )
{
if (this.InvokeRequired)
{
BoolEventHandler bHandler = new BoolEventHandler( this.ResignReply );
this.Invoke( bHandler, new object[] { clientAgreed } );
return;
}

// Code that changes controls in the main window form.
//

}

===============================================================

Basically I'm calling this method from a thread that has not created the
controls I want to change, so I have to call Invoke. The problem is I
sometimes get a NullReferenceException on the line with:

this.Invoke( . . . );

An unhandled exception of type 'System.NullReferenceException' occurred
in system.windows.forms.dll

Additional information: Object reference not set to an instance of an
object.

Call Stack:


system.windows.forms.dll!System.Windows.Forms.Control::MarshaledInvoke(Syste
m.Windows.Forms.Control

caller = {Backgammon.BackgammonForm}, System.Delegate method =
{Backgammon.BoolEventHandler}, System.Object[] args = {Length=1}, bool
synchronous = true) + 0x330 bytes



system.windows.forms.dll!System.Windows.Forms.Control::Invoke(System.Delegat
e

method = {Backgammon.BoolEventHandler}, System.Object[] args =
{Length=1}) + 0x30 bytes

Backgammon.exe!Backgammon.BackgammonForm.ResignReply(bool clientAgreed =
true) Line 1442 + 0xe bytes


I was hoping someone could explain to me why this is happening. On a
side note, I have almost identical code for a different method which
doesn't seem to throw the exception. . .

If you need more information, please let me know. . .

Many Thanks,

Derrick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top