我有一个C#项目,其中有很多事件。因此,有许多发布者和许多订阅者订阅该活动。我想要的是保持每个发布者的订阅者数量。
为简单起见,我在这里创建了一个基本场景。在此示例中,我想计算Class EventsCounter中每个发布者的订阅者数量。我在这里有很多问题。
在这里,我可以使用InvocationList,但我无法从其他类引用处理程序。例如Publisher.Foo给了我一个错误。
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");
}
}
}
答案 0 :(得分:1)
您可以声明Event类型的属性。这样,您就可以跟踪订阅和删除活动
此外,您可以通过调用事件的GetInvocationList()
方法来枚举订阅的处理程序。我在发布商的EnumerateSubscribers()
方法中证明了这一点
下面的代码是一个演示:
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);
}
}
}
}