C# 如何查明是否有人订阅了活动?
我有一个用例,我必须取消订阅一个活动。但在退订之前,我想确定这家伙是否真的迷上了这个活动C# 如何查明是否有人订阅了活动?,c#,event-handling,events,C#,Event Handling,Events,我有一个用例,我必须取消订阅一个活动。但在退订之前,我想确定这家伙是否真的迷上了这个活动 请告诉我如何实现这一点?假设是发布/订阅环境,只需呼叫提供商。取消订阅(EventType,subscriber)并让提供商确定订户是否已从以下位置订阅: //在受保护的虚拟方法中包装事件调用 //允许派生类重写事件调用行为 受保护的虚拟void OnRaiseCustomEvent(CustomEventArgs e) { //制作事件的临时副本,以避免 //最后一个订户取消订阅时的竞争条件 //在空检查
请告诉我如何实现这一点?假设是发布/订阅环境,只需呼叫提供商。取消订阅(EventType,subscriber)并让提供商确定订户是否已从以下位置订阅:
//在受保护的虚拟方法中包装事件调用
//允许派生类重写事件调用行为
受保护的虚拟void OnRaiseCustomEvent(CustomEventArgs e)
{
//制作事件的临时副本,以避免
//最后一个订户取消订阅时的竞争条件
//在空检查之后和引发事件之前。
EventHandler=RaiseCustomEvent;
//如果没有订阅服务器,则事件将为null
if(处理程序!=null)
{
//格式化要在CustomEventArgs参数内发送的字符串
e、 Message+=String.Format(“at{0}”,DateTime.Now.ToString());
//使用()运算符引发事件。
处理者(本,e);
}
}
您正在寻找if(handler!=null)部分。如果没有订阅者,则为null;如果有订阅者,则为null。示例类发布者提供一个事件发布。方法IsRegistered查询给定类实例的事件附加事件处理程序,如果该类实例至少有一个已注册/附加事件处理程序,则返回true。 被重写的IsRegistered方法执行相同的操作,但对于静态类型除外 将此代码放入控制台应用程序项目中,点击F5进行调试,然后尝试一下
internal class Publisher
{
internal event EventHandler<EventArgs> Publish;
internal bool IsRegistered(Type type)
{
if (Publish == null) return false;
//
return (from item in Publish.GetInvocationList() where item.Target == null & item.Method.DeclaringType == type select item).Count() > 0;
}
internal bool IsRegistered(object instance)
{
if (Publish == null) return false;
//
return (from item in Publish.GetInvocationList() where item.Target == instance select item).Count() > 0;
}
static int Main(string[] args)
{
Publisher p = new Publisher();
//
p.Publish += new EventHandler<EventArgs>(static_Publish);
p.Publish += new EventHandler<EventArgs>(p.instance_Publish);
//
Console.WriteLine("eventhandler static_Publish attach: {0}", p.IsRegistered(typeof(Program)));
Console.WriteLine("eventhandler instance_Publish attach: {0}", p.IsRegistered(program));
//
return 0;
}
void instance_Publish(object sender, EventArgs e)
{
}
static void static_Publish(object sender, EventArgs e)
{
}
}`
内部类发布器
{
内部事件处理程序发布;
内部布尔值已注册(类型)
{
if(Publish==null)返回false;
//
返回(来自Publish.GetInvocationList()中的项,其中item.Target==null&item.Method.DeclaringType==type选择项)。Count()>0;
}
内部bool已注册(对象实例)
{
if(Publish==null)返回false;
//
返回(来自Publish.GetInvocationList()中的项,其中item.Target==实例选择项)。Count()>0;
}
静态int Main(字符串[]args)
{
Publisher p=newpublisher();
//
p、 Publish+=新事件处理程序(静态发布);
p、 Publish+=新事件处理程序(p.instance\u Publish);
//
WriteLine(“eventhandler static_Publish attach:{0}”,p.IsRegistered(typeof(Program));
WriteLine(“eventhandler实例_发布附加:{0}”,p.IsRegistered(程序));
//
返回0;
}
无效实例发布(对象发送方,事件参数e)
{
}
静态无效静态发布(对象发送方、事件参数)
{
}
}`
有两种方法可以做到这一点:
.Contains
,来完成此操作private EventHandler _Changed;
public event EventHandler Changed
{
add
{
_Changed += value;
}
remove
{
EventHandler temp = _Changed - value;
if (_Changed == null || temp == _Changed)
throw new InvalidOperationException(
"Delegate is not subscribed, cannot unsubscribe");
_Changed = temp;
}
}
第二个类似于下面的代码,这将简单地查看您想要取消订阅的代理是否存在于代理链中
private EventHandler _Changed;
public event EventHandler Changed
{
add
{
_Changed += value;
}
remove
{
if (_Changed == null || !_Changed.GetInvocationList().Contains(value))
throw new InvalidOperationException(
"Delegate is not subscribed, cannot unsubscribe");
_Changed -= value;
}
}
请注意,如果您愿意,您可以使用类似的代码来处理两次添加代理的情况。这是一个非常特定于环境的问题-因此您应该提供一些关于语言/框架/平台的信息。您需要编辑您的问题,提供有关您的问题的更多信息。哦,这是来自C。下面是详细信息:假设有一个类a提供了一个事件ABC,而另一个类B已经注册了该事件。现在在某个方法中,我需要取消B的订阅。但是在取消订阅之前,我想确定这个家伙是否真的订阅了这个活动。现在我该怎么做呢?虽然你的帖子是准确的,但他想检查他是否已经为事件分配了特定的处理程序,而不是是否分配了任何处理程序(即,它不是null)。是的,Silky是正确的。我想知道是否已经附加了处理程序。当我们注册一个事件时,每次我们都会建立一个新的委托实例,这样我就不会让委托获取调用列表。不是吗?我们不查询委托实例本身,而是查询其上的目标属性。我们想知道类A是否已将事件处理程序注册到我们的事件(多播委托),因此我们查询事件上所有已注册的委托,以查找在目标属性中包含类A实例的委托,希望这能有所帮助
private EventHandler _Changed;
public event EventHandler Changed
{
add
{
_Changed += value;
}
remove
{
if (_Changed == null || !_Changed.GetInvocationList().Contains(value))
throw new InvalidOperationException(
"Delegate is not subscribed, cannot unsubscribe");
_Changed -= value;
}
}