Static instance Event fires more than one time

N

None

Hi,

I'm facing a problem with static instances. I have created a
class called CustomList by deriving the class List<int>. Inside the
CustomList i have created Remove event (when any item is removed from
the List). After that i have created a staic instance for the
CustomList in my WebService class. The class contains the Start And
Poll Methods. Inside the Start method i have added the Removed event.


Please execute the following code and you will notice that the
"objCustList_Removed" is called more than one time. I'm in a situation
that the "objCustList_Removed" function should not called more than
one time. Please let me know if anybody find solution.

Note : Also i'm in a situation that i want to use only static
instance.


using System;
using System.Collections.Generic;
using System.Text;

namespace TestConsole
{
class Main
{
public delegate void OnRemovedEventHandler(object sender,
System.EventArgs e);
public class CustomList : List<int>
{

public event OnRemovedEventHandler Removed;

protected virtual void OnRemoved(System.EventArgs e)
{
if (Removed != null)
{
Removed(this, e);
}
}

public new void Add(int i)
{
base.Add(i);
}

public new void Remove(int i)
{
base.Remove(i);
Removed(this, System.EventArgs.Empty);
}

public new void RemoveAt(int i)
{
base.RemoveAt(i);
Removed(this, System.EventArgs.Empty);
}

}
public class WebService
{
private static CustomList objCustList = new CustomList();
public WebService()
{
}
public int start(int i)
{
objCustList.Removed += new
OnRemovedEventHandler(objCustList_Removed);
objCustList.Add(i);
return i;
}
void objCustList_Removed(object sender, EventArgs e)
{
Console.WriteLine("Method Called More than one time");
}
public void poll(int i)
{
objCustList.Remove(i);

}

}
internal class Program
{
public static void Main()
{
WebService ws = new WebService();
int i1 = ws.start(1);

WebService ws1 = new WebService();
int i2 = ws1.start(2);

WebService ws2 = new WebService();
int i3 = ws2.start(3);

WebService ws3 = new WebService();
int i4 = ws3.start(4);

WebService ws4 = new WebService();
int i5 = ws4.start(5);


ws1.poll(i1);
Console.WriteLine("---------------------------");
ws2.poll(i2);
Console.WriteLine("---------------------------");
ws3.poll(i3);
Console.WriteLine("---------------------------");
ws4.poll(i4);
Console.WriteLine("---------------------------");
ws4.poll(i5);
Console.WriteLine("---------------------------");
Console.ReadLine();
}
}
}
}


Thanks,
Vinothkumar B
 
C

Christof Nordiek

None said:
Hi,

I'm facing a problem with static instances. I have created a
class called CustomList by deriving the class List<int>. Inside the
CustomList i have created Remove event (when any item is removed from
the List). After that i have created a staic instance for the
CustomList in my WebService class. The class contains the Start And
Poll Methods. Inside the Start method i have added the Removed event.

You call the start method 5 times. Each time you add a handler to the event.
After that, on any Remove all this handlers are called.

All instances of WebService use the same CustomList and all listen on the
Remove event. So each WebService react on each occurence of Remove

Wich WebService do you want to react?

Christof
 
M

Marc Gravell

Note related to the issue at hand, but a general pointer; it might be
desirable to expose this functionality via the standard
IBindingList.ListChanged event; fortunately, BindingList<T> does all
of this for you... it might save you some debugging time? Plus make
your list fully usable from MVP...

Marc
 
N

None

Hi Christof,

Thanks for your reply. I understand what is happening. I
want all the webservice has to reacat to the Remove event but only one
time (i.e, i want the "objCustList_Removed" has to be called only one
time during the Remove), eventhough many handlers are added. Is there
any other possibilites to achive this. (Without changing the static
instance)

Thanks and Regards,
Vinothkumar B
 
M

Marc Gravell

I'm not sure I fully understand what you are trying to do... if you
don't want to listen to an event any more, then unsubscribe from it.
If each item is interested in a single item from the list then use
instance events and have your Remove code fire removed instance's
event via a public/internal method such as OnRemoved() on the item.

A bigger word of warning: subscribing to static events is a really
easy way to cause a leak[*] if you aren't very careful to
unsubscribe...

*=not a true leak; the lost memory isn't in a disconnected island - it
is still visible to the static instance. But either way - you can
easily start chomping up the mibibytes...

Marc
 
N

Nicholas Paldino [.NET/C# MVP]

On a side note, it's interesting that the term "leak" is used for this
kind of situation. Given that it is a managed environment, you can't have
disconnected islands. If anything, you have "stuff" or "globs" of memory
hanging around which you need to disconnect (to make it eligible for GC), as
opposed to disconnected memory which you need to release.
 
N

Nicholas Paldino [.NET/C# MVP]

If you want an event handler to fire once for a particular event, then
you need to subscribe to the event only once. If you keep adding the event
handler, you are going to have that handler called multiple times for the
same event.
 
B

Bruce Wood

I had a long and fruitless disucssion about this some time ago.

I would claim that there are two kinds of memory leaks: true memory
leaks, in which the memory becomes a disconnected island and cannot be
recovered, and what I would call "conceptual memory leaks" in which
memory that you expect to be recovered isn't recovered.

The first kind of leak is theoretically impossible under .NET. The
second kind of leak happens all the time, and points out a
misunderstanding about how the C# language, or the .NET Framework,
operates.

On a side note, it's interesting that the term "leak" is used for this
kind of situation. Given that it is a managed environment, you can't have
disconnected islands. If anything, you have "stuff" or "globs" of memory
hanging around which you need to disconnect (to make it eligible for GC), as
opposed to disconnected memory which you need to release.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)




I'm not sure I fully understand what you are trying to do... if you don't
want to listen to an event any more, then unsubscribe from it. If each
item is interested in a single item from the list then use instance events
and have your Remove code fire removed instance's event via a
public/internal method such as OnRemoved() on the item.
A bigger word of warning: subscribing to static events is a really easy
way to cause a leak[*] if you aren't very careful to unsubscribe...
*=not a true leak; the lost memory isn't in a disconnected island - it is
still visible to the static instance. But either way - you can easily
start chomping up the mibibytes...
Marc- Hide quoted text -

- Show quoted text -
 
N

Nicholas Paldino [.NET/C# MVP]

Any suggestions on a catch-phrase we could coin? haha

Personally, I like "gunk" or "glob".

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bruce Wood said:
I had a long and fruitless disucssion about this some time ago.

I would claim that there are two kinds of memory leaks: true memory
leaks, in which the memory becomes a disconnected island and cannot be
recovered, and what I would call "conceptual memory leaks" in which
memory that you expect to be recovered isn't recovered.

The first kind of leak is theoretically impossible under .NET. The
second kind of leak happens all the time, and points out a
misunderstanding about how the C# language, or the .NET Framework,
operates.

On a side note, it's interesting that the term "leak" is used for
this
kind of situation. Given that it is a managed environment, you can't
have
disconnected islands. If anything, you have "stuff" or "globs" of memory
hanging around which you need to disconnect (to make it eligible for GC),
as
opposed to disconnected memory which you need to release.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)




I'm not sure I fully understand what you are trying to do... if you
don't
want to listen to an event any more, then unsubscribe from it. If each
item is interested in a single item from the list then use instance
events
and have your Remove code fire removed instance's event via a
public/internal method such as OnRemoved() on the item.
A bigger word of warning: subscribing to static events is a really easy
way to cause a leak[*] if you aren't very careful to unsubscribe...
*=not a true leak; the lost memory isn't in a disconnected island - it
is
still visible to the static instance. But either way - you can easily
start chomping up the mibibytes...
Marc- Hide quoted text -

- Show quoted text -
 
M

Marc Gravell

How about a memory "abscess" - still attached and puddling, but
useless waste... or "slag" (presumably, then, the GC in CLR4.0 might
move these to the "slag heap"; I'll get my coat...)?

Neither is very pretty, though ;-p

Marc
 

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