我有一个用例,我必须取消订阅活动。但是在取消订阅之前,我想确定这个人是否已经真正地吸引了这个事件。
请告诉我如何实现这一目标?
答案 0 :(得分:3)
来自Microsoft:
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> handler = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (handler != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += String.Format(" at {0}", DateTime.Now.ToString());
// Use the () operator to raise the event.
handler(this, e);
}
}
您正在寻找 if(handler!= null)部分。如果没有订阅者,则 null ,如果有订阅者,则 not null 。
答案 1 :(得分:1)
示例类Publisher提供一个事件Publish。 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)
{
}
}`
答案 2 :(得分:0)
答案 3 :(得分:0)
有两种方法可以做到这一点:
.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;
}
}
请注意,如果需要,您可以使用类似的代码来处理两次添加委托的情况。