嗯..不确定我是否理解正确。这样的事情怎么样?使用模式
public void handleui(dynamic s)
{
Application.Current.Dispatcher.Invoke(delegate
{
btn1.Content = s.ToString();
});
}
Globals.Events["error"] += msg=> Console.WriteLine(msg);//logger perhaps
Globals.Events["productb"] += handleui;//sub
Globals.Events["productb"] -= handleui;//unsub
Globals.Events["productb"].Send("productbdata");//raise the event or publish to productb channel subscribers
Globals.Events.Send("broadcast?");
我想您可能会做一个过滤器,它只是将所有事件发送到 Events["producta"]、Events["productb"]、Events["productc"] 等,并且这些部分可以在需要时进行 sub/unsub。
执行。
using System;
using System.Collections.Concurrent;
public class Globals
{
public static MsgBus Events = new MsgBus();
}
public class MsgBus
{
private readonly ConcurrentDictionary<dynamic, MsgChannel> channels = new ConcurrentDictionary<dynamic, MsgChannel>();
public MsgChannel this[dynamic channel]
{
set { channels[channel] = value; }
get
{
var ch = (MsgChannel)channels.GetOrAdd(channel, new MsgChannel());
return ch;
}
}
private MsgChannel broadcast = new MsgChannel();
public void Send(dynamic msg)
{
broadcast.Send(msg);
}
public static MsgBus operator +(MsgBus left, Action<dynamic> right)
{
left.broadcast += right;
return left;
}
public static MsgBus operator -(MsgBus left, Action<dynamic> right)
{
left.broadcast -= right;
return left;
}
}
public class MsgChannel
{
ConcurrentDictionary<Action<dynamic>, int> observers = new ConcurrentDictionary<Action<dynamic>, int>();
public void Send(dynamic msg)
{
foreach (var observer in observers)
{
for (int i = 0; i < observer.Value; i++)
{
observer.Key.Invoke(msg);
}
}
}
public static MsgChannel operator +(MsgChannel left, Action<dynamic> right)
{
if (!left.observers.ContainsKey(right))
{
left.observers.GetOrAdd(right, 0);
}
left.observers[right]++;
return left;
}
public static MsgChannel operator -(MsgChannel left, Action<dynamic> right)
{
if (left.observers.ContainsKey(right) &&
left.observers[right] > 0)
{
left.observers[right]--;
int dummy;
if (left.observers[right] <= 0) left.observers.TryRemove(right, out dummy);
}
return left;
}
}