I have a little problem with my objects... I have an object with one delegate inside to which it subscribe in constructor. When I destroy this object the invocation list still tell me that it has one subscriber in. and when and create this object again I find two subscriber in (the old that I have destroyed and the new one). How can I solve this problem and remove the subscriber in the list cleanly?
Here is the code for test:(two button to destroy and create object inside)
public partial class Form1 : Form
{
testdelegate thisdelegatetest;
public Form1()
{
InitializeComponent();
thisdelegatetest = new testdelegate();//create object
Timer mytimer = new Timer();//timer to see something BEGIN
mytimer.Interval = 1000;
mytimer.Tick += new EventHandler(mytimer_Tick);
mytimer.Start();//timer to see something END
}
protected void mytimer_Tick(object sender, EventArgs e)
{//each 1second look at the list invocation
lb_IndelList.Text = "actual subscribers : " + testdelegate.dl_myfunctionthatcopy.GetInvocationList().Count().ToString();
}
private void DestroyObject_Click(object sender, EventArgs e)
{//destroy object
/*edit*/
thisdelegatetest.Delete();
thisdelegatetest = null;//dereferencing for GC
/*edit*/
}
private void CreateObject_Click(object sender, EventArgs e)
{//create object
thisdelegatetest = new testdelegate();
}
}
public class testdelegate
{
public delegate void del_copysomething(int newvaluetocopy);
internal static del_copysomething dl_myfunctionthatcopy;
public int valueforallobject = 0;
public testdelegate()//ctor
{
dl_myfunctionthatcopy += new del_copysomething(copythisint);
}
/*edit*/
public void Delete()
{
dl_myfunctionthatcopy -= new del_copysomething(copythisint);
}
/*edit*/
private void copythisint(int newvalue)
{
valueforallobject = newvalue;
}
}
Thanks for your help.
Since you cannot call the destructor manually, why not implementing the IDisposable
interface and execute the unregistering in the Dispose
method?=!
public class testdelegate : IDisposable
{
public delegate void del_copysomething(int newvaluetocopy);
internal static del_copysomething dl_myfunctionthatcopy;
public int valueforallobject = 0;
public testdelegate()//ctor
{
dl_myfunctionthatcopy += new del_copysomething(copythisint);
}
private void copythisint(int newvalue)
{
valueforallobject = newvalue;
Console.WriteLine("Copied");
}
public void Dispose()
{
dl_myfunctionthatcopy -= new del_copysomething(copythisint);
GC.SuppressFinalize(this);
}
}
In the DestroyObject_Click
method you would just call the Dispose
method:
private void DestroyObject_Click(object sender, EventArgs e)
{ //call Dispose destroy object
thisdelegatetest.Dispose();
}