I have this method that can be used as a delegate. Because of reasons, I want it to do some stuff only once for each time the event fires.
//In the real code those lines are in very different places
btn.Click += foo.DoOnlyOnce;
btn.Click += foo.DoOnlyOnce;
will result in only one execution of DoStuff()
private List<EventArgs> _eventArgsList = new List<EventArgs>();
public void DoOnlyOnce(object sender, EventArgs e)
{
if (!_eventArgsList.Contains(e))
{
_eventArgsList.Add(e);
DoStuff();
}
}
If the btn is Clicked twice, it still does DoStuff() twice, as intended.
A problem with this solution is _eventArgsList
it will keep track of the eventArgs indefinitely. A memoryleak is born since GC will not dispose it like it would normally do once all subscriptions are handled.
Can I somehow get the original event in the delegate?
For example something like
GetOriginalEvent().GetInvocationList()
Would help me to determinate when it is a good time to clear the list.
Or, can I solve this in a better way? I was originally starting to try something like:
var handler = new DoEventOnlyOnce(btn.Click);
handler.DoOnlyOnce += DoStuff;
handler.DoOnlyOnce += DoStuff;
So you could have a reference to the original event. But didn't get that working.
You could argue that I should always do
btn.Click -= foo.DoOnlyOnce;
btn.Click += foo.DoOnlyOnce;
But I want this logic inside DoOnlyOnce so I don't have to rely on the correct usage.