Reputation:
I have a C# project where there are a number of events. So, there a number of publisher and a number of subscribers that subscribe to that event. What I want is to keep a count of subscribers to each of the publishers.
For simplicity, I have created a basic scenario here. In this example, I want to count the number of subscribers to each publisher in Class EventsCounter. I have a number of questions here.
Here, I could use the InvocationList but I could not reference the handler from a different class. e.g. Publisher.Foo gave me an error.
using System;
namespace EventTest
{
class Program
{
static void Main(string[] args)
{
GenerateEvents ge = new GenerateEvents();
}
}
public class EventsCounter
{
//need to count all events and corresponding subscribers here
}
public class GenerateEvents
{
public GenerateEvents()
{
Publisher publisher = new Publisher();
Subscriber subscriber1 = new Subscriber();
Subscriber subscriber2 = new Subscriber();
publisher.Foo += subscriber1.FooHandler;
publisher.Foo += subscriber2.FooHandler;
publisher.RaiseFoo();
publisher.Foo -= subscriber1.FooHandler;
publisher.Foo -= subscriber2.FooHandler;
publisher.RaiseFoo();
Console.Read();
}
}
public class Publisher
{
public event EventHandler Foo;
int count = 0;
public void RaiseFoo()
{
Console.WriteLine("Raising Foo");
EventHandler handler = Foo;
if (handler != null)
{
foreach (EventHandler subscriber in handler.GetInvocationList())
{
count++;
subscriber(this, EventArgs.Empty);
}
Console.WriteLine("The count is {0}", count);
}
else
{
Console.WriteLine("No subscribers!");
}
}
}
public class Subscriber
{
public void FooHandler(object sender, EventArgs e)
{
Console.WriteLine("Subscriber Called");
}
}
}
Upvotes: 3
Views: 242
Reputation: 1047
You might declare a property of type Event. This way, you can track subscription to and removal from your event.
Also, you can enumerate through subscribed handlers by calling your event's GetInvocationList()
method. I demonstrated this within the publisher's EnumerateSubscribers()
method.
Below code is a demonstration:
using System;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
var p = new Publisher();
var s1 = new Subscriber("first");
s1.Subscribe(p);
p.RaiseFoo(null, null);
var s2 = new Subscriber("second");
s2.Subscribe(p);
p.RaiseFoo(null, null);
p.EnumerateSubscribers();
s1.Unsubscribe(p);
p.RaiseFoo(null, null);
s2.Unsubscribe(p);
Console.ReadKey();
}
}
public class Subscriber
{
public string Name { get; set; }
public Subscriber(string name)
{
this.Name = name;
}
public void Subscribe(Publisher p)
{
p.Foo += this.HandleFoo;
}
public void Unsubscribe(Publisher p)
{
p.Foo -= this.HandleFoo;
}
private void HandleFoo(object sender, EventArgs e)
{
Console.WriteLine(this.Name + " is called");
}
public override string ToString()
{
return this.Name;
}
}
public class Publisher
{
private int count;
private EventHandler _foo;
public void RaiseFoo(object sender, EventArgs e)
{
if (_foo != null)
{
_foo(sender, e);
}
}
public void EnumerateSubscribers()
{
if (_foo != null)
{
foreach (var item in _foo.GetInvocationList())
{
Console.WriteLine("Subscriber object:" + item.Target?.ToString());
}
}
}
public event EventHandler Foo
{
add
{
_foo += value;
Console.WriteLine("Count:" + ++count);
}
remove
{
_foo -= value;
Console.WriteLine("Count:" + --count);
}
}
}
}
Upvotes: 1