473,666 Members | 2,075 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Raising events

Can someone explain why this code DOES NOT raise a null reference exception?
//////////////////////////// Program.cs
/////////////////////////////////////////////
using System;
using System.Collecti ons.Generic;
using System.Text;
using CSharpLib;

namespace CSharpConsole
{
class Program
{
private EventHandler handler;
private Class1 obj;

static void Main(string[] args)
{
(new Program()).RunT est();
Console.ReadKey (true);
}

private Program()
{
obj = new Class1();
handler = new EventHandler(Do Something);
}

private void RunTest()
{
obj.SomeEvent += handler;

obj.RaiseEvent( delegate { obj.SomeEvent -= handler; });
}

private void DoSomething(obj ect sender, EventArgs e)
{
Console.WriteLi ne("foo");
}
}
}
//////////////////////////// Class1.cs
/////////////////////////////////////////////
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace CSharpLib
{
public class Class1
{
public event EventHandler SomeEvent;

public delegate void Callback();

public Class1()
{
}

public void RaiseEvent(Call back callback)
{
EventHandler temp = SomeEvent;

callback();

if (temp != null)
{
temp(this, EventArgs.Empty );
}
}
}
}


Oct 28 '06 #1
9 1829
"CuriousGeo rge" <***@***.comwro te in message
news:Ot******** ********@TK2MSF TNGP03.phx.gbl. ..
Can someone explain why this code DOES NOT raise a null reference
exception?
Because no nulls are referenced?

If you have reason to believe that a null reference exception should occur,
then the least you could do is explain in your post:
a) why it is you want to execute code like this, and
b) why and where it is that you think a null reference exception would
occur

Pete
Oct 28 '06 #2
Hi,

Where do you expect a null reference exception to be raised?

This line is checking to make sure temp is not null before it's used in
Class1:

if (temp != null)

--
Dave Sexton

"CuriousGeo rge" <***@***.comwro te in message
news:Ot******** ********@TK2MSF TNGP03.phx.gbl. ..
Can someone explain why this code DOES NOT raise a null reference exception?
//////////////////////////// Program.cs
/////////////////////////////////////////////
using System;
using System.Collecti ons.Generic;
using System.Text;
using CSharpLib;

namespace CSharpConsole
{
class Program
{
private EventHandler handler;
private Class1 obj;

static void Main(string[] args)
{
(new Program()).RunT est();
Console.ReadKey (true);
}

private Program()
{
obj = new Class1();
handler = new EventHandler(Do Something);
}

private void RunTest()
{
obj.SomeEvent += handler;

obj.RaiseEvent( delegate { obj.SomeEvent -= handler; });
}

private void DoSomething(obj ect sender, EventArgs e)
{
Console.WriteLi ne("foo");
}
}
}
//////////////////////////// Class1.cs
/////////////////////////////////////////////
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace CSharpLib
{
public class Class1
{
public event EventHandler SomeEvent;

public delegate void Callback();

public Class1()
{
}

public void RaiseEvent(Call back callback)
{
EventHandler temp = SomeEvent;

callback();

if (temp != null)
{
temp(this, EventArgs.Empty );
}
}
}
}


Oct 28 '06 #3
Because no nulls are referenced?
Hmmm. OK.

a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

b) Events are basically delegates, System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than that
its a pretty vanilla type.

As we know and event with no subscribers is actually a null-reference hence
the check for nullility before invoking the subscribed handlers.

If you in-line the delegate call in my original post you get something like
the following (compiled in Outlook Express)

public void RaiseEvent(Call back callback)
{
EventHandler temp = SomeEvent;

SomeEvent -= theOnlyRegister edEventHandler
//SomeEvent is now null

if (temp != null)
{
temp(this, EventArgs.Empty );
}
}

The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.
"Peter Duniho" <Np*********@Nn OwSlPiAnMk.comw rote in message
news:12******** *****@corp.supe rnews.com...
"CuriousGeo rge" <***@***.comwro te in message
news:Ot******** ********@TK2MSF TNGP03.phx.gbl. ..
>Can someone explain why this code DOES NOT raise a null reference
exception?

Because no nulls are referenced?

If you have reason to believe that a null reference exception should
occur, then the least you could do is explain in your post:
a) why it is you want to execute code like this, and
b) why and where it is that you think a null reference exception would
occur

Pete

Oct 28 '06 #4
Hi,
a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.
I don't see anything particularly thread safe about your code, are you
talking about checking for null that makes this thread safe? It is safe for
a single thread but once you have multiple threads the really only safe way
is to make sure you have locks in place around adding/removing delegates to
your event and the invocation of that event i.e. the following is an example
of how two threads accessing the same event can cause a null reference
exception:

using System.Threadin g;

namespace CSharpConsole
{
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
t.Run();
}
}

class TestClass
{
private delegate void MyEventHandler( );
private event MyEventHandler MyEvent;

public TestClass()
{
}

public void Run()
{
Thread threadA = new Thread(new ThreadStart(Thr eadADoSomething ));

//Add listener to the event
MyEvent += new MyEventHandler( DoSomething);

if (MyEvent != null)
{
//got in here, let the other thread run and wait until it
//completes
threadA.Start() ;
threadA.Join();

//whoops now this is null
MyEvent();
}
}

void ThreadADoSometh ing()
{
//removes the only listener
MyEvent -= new MyEventHandler( DoSomething);
}

void DoSomething()
{
}
}
}
b) Events are basically delegates, System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than that
its a pretty vanilla type.
There is a little bit more to this type, hence your posting :-) If you look
at the documentation for the delegate type you will see: "Delegates are
immutable; once created, the invocation list of a delegate does not change."
Hence the reason why when you assign you event (which is really just
syntactic sugar around delgates) to your other delegate type really you have
just made a new copy of that delegate. The contents of the
multicastdelega tes invocation list inside the temp variable will therefore
not change when you update the other multicastdelega te through the SomeEvent
enty point.

The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.
Why not just ask the question you want to ask :-)
--
http://www.markdawson.org
Posted from Windows Vista RC1

"CuriousGeo rge" wrote:
Because no nulls are referenced?
Hmmm. OK.

a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

b) Events are basically delegates, System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than that
its a pretty vanilla type.

As we know and event with no subscribers is actually a null-reference hence
the check for nullility before invoking the subscribed handlers.

If you in-line the delegate call in my original post you get something like
the following (compiled in Outlook Express)

public void RaiseEvent(Call back callback)
{
EventHandler temp = SomeEvent;

SomeEvent -= theOnlyRegister edEventHandler
//SomeEvent is now null

if (temp != null)
{
temp(this, EventArgs.Empty );
}
}

The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.
"Peter Duniho" <Np*********@Nn OwSlPiAnMk.comw rote in message
news:12******** *****@corp.supe rnews.com...
"CuriousGeo rge" <***@***.comwro te in message
news:Ot******** ********@TK2MSF TNGP03.phx.gbl. ..
Can someone explain why this code DOES NOT raise a null reference
exception?
Because no nulls are referenced?

If you have reason to believe that a null reference exception should
occur, then the least you could do is explain in your post:
a) why it is you want to execute code like this, and
b) why and where it is that you think a null reference exception would
occur

Pete


Oct 28 '06 #5
"Delegates are immutable; once created, the invocation list of a delegate
does not change."

Word. Thanks Mark, I hadn't seen that bit of doco. The thing is, I did skim
the (managed) rotor source for delegates and saw nothing that suggested
immutability in the implementation. Forgive my ignorance but where in the IL
can I see this? (is it a type decorator)

"Why not just ask the question you want to ask :-)"

Quite simply, I don't have the expertise to express myself very well.

Case in point, immutability, I see it, I hear it, it is said by the oracle,
MSDN, however, the upshot is (to all intents and purposes) that the
assignment operator behaves like it is overloaded such that it works like a
value type. I have taken this as gospel for years with the System.String
class but now I see it here and it is making my head spin!!

Words fail me.

Please help :)
"Mark R. Dawson" <Ma*********@di scussions.micro soft.comwrote in message
news:A1******** *************** ***********@mic rosoft.com...
Hi,
>a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

I don't see anything particularly thread safe about your code, are you
talking about checking for null that makes this thread safe? It is safe
for
a single thread but once you have multiple threads the really only safe
way
is to make sure you have locks in place around adding/removing delegates
to
your event and the invocation of that event i.e. the following is an
example
of how two threads accessing the same event can cause a null reference
exception:

using System.Threadin g;

namespace CSharpConsole
{
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
t.Run();
}
}

class TestClass
{
private delegate void MyEventHandler( );
private event MyEventHandler MyEvent;

public TestClass()
{
}

public void Run()
{
Thread threadA = new Thread(new
ThreadStart(Thr eadADoSomething ));

//Add listener to the event
MyEvent += new MyEventHandler( DoSomething);

if (MyEvent != null)
{
//got in here, let the other thread run and wait until it
//completes
threadA.Start() ;
threadA.Join();

//whoops now this is null
MyEvent();
}
}

void ThreadADoSometh ing()
{
//removes the only listener
MyEvent -= new MyEventHandler( DoSomething);
}

void DoSomething()
{
}
}
}
>b) Events are basically delegates, System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than
that
its a pretty vanilla type.

There is a little bit more to this type, hence your posting :-) If you
look
at the documentation for the delegate type you will see: "Delegates are
immutable; once created, the invocation list of a delegate does not
change."
Hence the reason why when you assign you event (which is really just
syntactic sugar around delgates) to your other delegate type really you
have
just made a new copy of that delegate. The contents of the
multicastdelega tes invocation list inside the temp variable will therefore
not change when you update the other multicastdelega te through the
SomeEvent
enty point.

>The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.

Why not just ask the question you want to ask :-)
--
http://www.markdawson.org
Posted from Windows Vista RC1

"CuriousGeo rge" wrote:
Because no nulls are referenced?
Hmmm. OK.

a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

b) Events are basically delegates, System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than
that
its a pretty vanilla type.

As we know and event with no subscribers is actually a null-reference
hence
the check for nullility before invoking the subscribed handlers.

If you in-line the delegate call in my original post you get something
like
the following (compiled in Outlook Express)

public void RaiseEvent(Call back callback)
{
EventHandler temp = SomeEvent;

SomeEvent -= theOnlyRegister edEventHandler
//SomeEvent is now null

if (temp != null)
{
temp(this, EventArgs.Empty );
}
}

The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.
"Peter Duniho" <Np*********@Nn OwSlPiAnMk.comw rote in message
news:12******* ******@corp.sup ernews.com...
"CuriousGeo rge" <***@***.comwro te in message
news:Ot******** ********@TK2MSF TNGP03.phx.gbl. ..
Can someone explain why this code DOES NOT raise a null reference
exception?

Because no nulls are referenced?

If you have reason to believe that a null reference exception should
occur, then the least you could do is explain in your post:
a) why it is you want to execute code like this, and
b) why and where it is that you think a null reference exception
would
occur

Pete



Oct 28 '06 #6
"CuriousGeo rge" <***@***.comwro te in message
news:%2******** **********@TK2M SFTNGP02.phx.gb l...
a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.
I disagree. As Mark points out, there's nothing thread-safe about the code
that you posted.
[...]
The code in my original post draws the understanding reader to the
conclusion that this particular reference type is not obeying standard
reference type semantics. I thought it was pretty self-explanatory.
Well, hopefully at this point, given the responses you've seen, it should be
clear to you that it was NOT "pretty self-explanatory".

On the bright side, it looks like you did finally get the answer to your
question. :)

Pete
Oct 28 '06 #7
CuriousGeorge <***@***.comwro te:
Because no nulls are referenced?
Hmmm. OK.

a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.
It's not, actually. Your code isn't genuinely thread-safe. See
http://www.pobox.com/~skeet/csharp/t...ckchoice.shtml for a
genuinely thread-safe pattern.
b) Events are basically delegates
No they're not. Events are pairs of methods. Field-like events declare
both an event and a delegate.
System.Delegate is a reference type,
there's nothing special about it, it overloads += and -= but other than that
its a pretty vanilla type.
Actually, it *doesn't* overload += and -=. Instead, the C# compiler
calls Delegate.Combin e or Delegate.Remove , both of which are static
methods which can take null arguments.

See http://www.pobox.com/~skeet/csharp/events.html for more
information.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 29 '06 #8
Peter Duniho <Np*********@Nn OwSlPiAnMk.comw rote:
"CuriousGeo rge" <***@***.comwro te in message
news:%2******** **********@TK2M SFTNGP02.phx.gb l...
a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

I disagree. As Mark points out, there's nothing thread-safe about the code
that you posted.
In fairness to the OP, I wouldn't go that far. It's not *quite* thread-
safe, but it's safer than the normal pattern of:

if (EventName != null)
{
EventName (...);
}

where "EventName" is a field-like event.

The problem with the above is that another thread could change the
value of myEventName to null between the check and the call. The OP's
code tries to avoid that by using a local variable. Now, there's some
debate as to the exact guarantees of behaviour of local variables in
the memory model, but it's at least a reasonable start. However, the
lack of locking and volatility means that if one thread adds a load of
event handlers, they may never be noticed by the thread raising the
event, which isn't generally what's wanted.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 29 '06 #9
Jon, your arachsys stuff is, quite simply, GOLD

"Jon Skeet [C# MVP]" <sk***@pobox.co mwrote in message
news:MP******** *************** *@msnews.micros oft.com...
CuriousGeorge <***@***.comwro te:
Because no nulls are referenced?
Hmmm. OK.

a) "Code like this" is the preferred way to raise events in a thread safe
manor - you should be doing it yourself.

It's not, actually. Your code isn't genuinely thread-safe. See
http://www.pobox.com/~skeet/csharp/t...ckchoice.shtml for a
genuinely thread-safe pattern.
>b) Events are basically delegates

No they're not. Events are pairs of methods. Field-like events declare
both an event and a delegate.
>System.Delegat e is a reference type,
there's nothing special about it, it overloads += and -= but other than
that
its a pretty vanilla type.

Actually, it *doesn't* overload += and -=. Instead, the C# compiler
calls Delegate.Combin e or Delegate.Remove , both of which are static
methods which can take null arguments.

See http://www.pobox.com/~skeet/csharp/events.html for more
information.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Oct 29 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2091
by: serge calderara | last post by:
Dear all, I have a class wich is raising events as normally it should do. having a form in the same assembly wich is catching those events works fne. Raise events gets catch normaly within the form and I can process what I want based on them. If I try to catch raised events by this class but within a form located in a different assembly, I am not able to
6
2866
by: Dan | last post by:
I've created a pocketpc app which has a startup form containing a listview. The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a TimerState object similar to the example in the System.Threading.Timer documentation. The method which handles the timer events, among other things, periodically calls a method in this TimerState object which raises an event to the startup form,...
4
17267
by: rawCoder | last post by:
Hi all, How Can You Raise Events Asynchronously ? Now for the details ... I want to do inter modular communication using events in such a way that the contributing modules need not maintain the reference to any module.
7
2439
by: cider123 | last post by:
I'm coding a project using the following article as reference: http://www.codeproject.com/csharp/DynamicPluginManager.asp In this type of project, plugins are loaded dynamically into a Plugin Manager. Your main application then hooks into the Plugin Manager. What I'm trying to figure out is how to impliment some form of raising
0
1721
by: Greg Park | last post by:
I have many user controls loading into a web page using Page.LoadControl However, I'm unable to figure out how to raise an event when a button is click or a check box is checked. I can have upto a hundred user controls on a single page and AutoPostBack isn't an option. I have no problem with raising events when an user control is dropped on the aspx page.
0
1445
by: Joe Campbell | last post by:
I am encountering a problem raising WMI events from an asp.net application. The error received (as captured in the event log) is as follows: System.Runtime.InteropServices.COMException (0x80041003): Exception from HRESULT: 0x80041003. at Microsoft.EnterpriseInstrumentation.EventSinks.WmiEventSink ..Write(Object eventToRaise) at
4
1592
by: Dave A | last post by:
I am developing a somewhat complex component at the moment and coincidently I am also reading the Framework Design Guidelines book. After reading the section about event raising I have re-written the way my component raises events to follow the Framework Design Guides verbatim; ie (object sender, EventArgs (or some subclass there of) e). The thing that was not explained is why should I need to cast the sender to 'object' when I know...
2
1692
by: Gman | last post by:
Hi, I have created a usercontrol, a grid control essentially. Within it I have a class: clsGridRecord. I have coded the events such that when a user clicks on the grid, say, the events occur on the parent form. This is fine. The problem occurs when I want to raise an event for a user clicking on one of the clsRecords which are on the grid. So I've placed: Public Event GridRecordClicked(ByVal rec As clsGridRecord,
0
1249
by: Apu Nahasapeemapetilon | last post by:
Suggestions on cross-posting this issue would be appreciated. I've got a C# .NET DLL (CLR v1.1) that raises events into its container. When the container is a .NET application, raising the events work everytime. When the container is Internet Explorer, raising the events work on some PCs, but generate the exception: "object does not match target type" on some other PCs.
7
2867
by: Christian Cambier | last post by:
Hi, I have a textbox in a web user control. I then add the usercontrol to a web form. I also add a label in the web form. Now, when I press a key in the textbox, i want to display some text in the label. I tried by raising events as used in Winforms but it is not as easy as
0
8356
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8871
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8783
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8552
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8640
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6198
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4369
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2773
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2011
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.