首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在C#中订阅事件之前取消订阅事件会发生什么情况?

在C#中,如果在订阅事件之前取消订阅事件,将不会发生任何异常或错误。取消订阅事件的操作会被忽略,事件仍然可以正常触发并调用已订阅的事件处理程序。这是因为在C#中,事件的订阅和取消订阅是通过委托来实现的。

当我们订阅一个事件时,实际上是将一个委托实例添加到事件的委托列表中。当事件被触发时,委托列表中的所有委托实例都会被调用。如果在订阅事件之前取消订阅事件,即使委托实例已经从委托列表中移除,事件仍然会触发并尝试调用已经取消订阅的委托实例。由于委托实例已经被移除,调用将会失败,但不会引发任何异常。

这种情况下,可以通过在事件处理程序中进行判断来避免调用已取消订阅的委托实例。可以使用条件语句或者使用C# 6.0引入的空条件运算符(?.)来检查委托实例是否为null,如果为null则表示已取消订阅,可以避免调用。

以下是一个示例代码:

代码语言:txt
复制
public class EventPublisher
{
    public event EventHandler MyEvent;

    public void PublishEvent()
    {
        MyEvent?.Invoke(this, EventArgs.Empty);
    }
}

public class EventSubscriber
{
    public void Subscribe(EventPublisher publisher)
    {
        publisher.MyEvent += HandleEvent;
    }

    public void Unsubscribe(EventPublisher publisher)
    {
        publisher.MyEvent -= HandleEvent;
    }

    private void HandleEvent(object sender, EventArgs e)
    {
        Console.WriteLine("Event handled");
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        EventPublisher publisher = new EventPublisher();
        EventSubscriber subscriber = new EventSubscriber();

        subscriber.Subscribe(publisher);
        publisher.PublishEvent();

        subscriber.Unsubscribe(publisher);
        publisher.PublishEvent();
    }
}

在上述示例中,当调用subscriber.Unsubscribe(publisher)取消订阅事件后,再次调用publisher.PublishEvent()时,事件处理程序HandleEvent将不会被调用。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C# 事件订阅和解阅

类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。..."); } 为了避免重复加载的问题,装载新事件前先把原来的事件卸载掉; 事件装载也可以简写如下; 请注意,下面的语法是 C# 2.0 的新语法。...,事件取消订阅过程将比较麻烦。...这种情况下若要取消订阅,必须返回到该事件订阅代码,将该匿名方法存储委托变量,然后将此委托添加到该事件。一般来说,如果必须在后面的代码取消订阅某个事件,则建议您不要使用匿名函数订阅事件。...也就是,订阅妈妈的开饭消息。让妈妈做完饭开饭时,发布吃饭消息时,告诉爸爸和孩子一声。 这种机制就是C#的,订阅发布。

80020

每个.NET开发都应掌握的C#委托事件知识点

其中,委托和事件C#不可或缺的关键概念,每个.NET开发者都应该深入理解它们的作用和用法。...这允许委托的方法在后台线程执行,而不会阻塞当前线程。小编在之前的webform开发遇到下载进度条卡死的问题就是用它解决的。...; Console.WriteLine("取消一个订阅者的订阅..."); // 取消订阅一个订阅者 subscriber1.Unsubscribe(publisher...在这个示例,TemperatureMonitor 类充当了被观察者(发布者),Program 类的 OnTemperatureChanged 方法充当观察者(订阅者) 结语 委托和事件C#的重要概念...,C#无论是实现回调机制、处理异步操作,还是实现事件驱动的架构,委托和事件都是不可缺的,每个.NET开发者都应该深入了解和熟练掌握。

20910

C#与Redis】--高级主题--Redis 发布订阅

易于扩展: 发布订阅模式使系统更容易扩展,因为新增的模块只需订阅感兴趣的主题即可,而不需要修改现有的代码。 事件日志和审计: 发布订阅模式使得可以轻松地记录系统中发生事件,以便后续审计和分析。...系统集成和事件驱动架构: 发布订阅模式是事件驱动架构的关键组成部分,用于不同系统和模块之间进行松散耦合的通信,促使系统更具弹性和可维护性。 这些场景只是发布订阅模式实际应用的一部分示例。... Redis 订阅者和发布者是完全解耦的,这使得它成为构建实时通信和事件驱动系统的强大工具。下面是一个简单的示例,演示了如何使用 C# 来实现 Redis 的发布订阅模式。...你可以运行多个订阅者程序,如前一个示例所示,来测试消息的发布和订阅工作方式。确保订阅者程序运行之前,先运行发布者程序,以便订阅者可以接收到发布的消息。... C# ,可以使用不同的序列化库来处理消息的序列化和反序列化。

39810

C#委托和事件

多线程环境下,挂接事件时和对象创建所在的线程不同,那事件处理函数的代码将在哪个线程执行?   当代码的层次复杂时,开放委托和事件是不是带来更大的麻烦?      ...-= TestOnBoiled;    实际开发,这种情况是很普遍的,谁都有可能取消订阅多次,结果如何呢?...自从学习匿名函数后,笔者就特别喜欢用它,除非代码量特别长,否则十行之内的事件订阅,我都会用匿名函数。可是事情变得有意思了,写了匿名函数后,几乎没人记得取消订阅,那么,发生了什么事情呢?      ...一种是将构造函数写在一个新线程,另外一种是将事件订阅函数写在新线程,两者会发生怎样的情况呢? 3....本文介绍了C#的委托和事件订阅取消订阅,并在匿名函数和多线程两个环境下讨论了一些问题。如果你觉得这篇文章对你有帮助,请点一下推荐,若有任何问题,欢迎留言讨论,共同学习。

73720

C# 基础知识系列- 11 委托和事件

前言 事件和委托是C#的高级特性,也是C#很有意思的一部分。出现事件的地方,必然有委托出现;而委托则不一定会有事件出现。那为什么会出现这样的关系呢?...事件 事件,event。C#事件就像是一种机制,程序运行到一定阶段的时候或者遇到某些状况的时候,就会触发一个事件。然后如果有其他代码订阅了这个事件,就会自动执行订阅的代码。...描述起来很抽象,简单来讲就是类声明一个委托,并标记这个委托是一个事件另一个方法执行这个事件。其中,触发这个事件的类称为发布者,接受或者注册了处理方法的类称为订阅者。 如何创建或声明一个事件?...所以开发,我们自己定义一个事件变量类型,为了保持一致继承EventArgs。 C#建议事件的定义以On开头,表示什么时触发,示例代码并不符合这个规范。 3....到这里,委托和事件的基本概念就已经介绍完毕了,当然还是那句话,更多的内容在实践C#事件机制让程序员有更多的自由去自定义事件,而不是被局限某些框架内。

83220

C#的委托和事件 - Part.2

C#的委托和事件 - Part.2 引言 如果你看过了 C#的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识。但那些远不是委托和事件的全部内容,还有很多的地方没有涉及。... C#的委托和事件 ,我提出了两个为什么类型中使用事件向外部提供方法注册,而不是直接使用委托变量的原因。...,它只要在事件发生的那一瞬间告知订阅事件已经发生并将相关参数传给订阅者就可以了。...现在我们来看下如何解决这个问题,先回顾一下之前C#的委托和事件一文中提到的内容,我说过,委托的定义会生成继承自MulticastDelegate的完整的类,其中包含Invoke()、BeginInvoke...总结 这篇文章是对我之前写的C#的委托和事件的一个补充,大致分为了三个部分,第一部分讲述了几个容易让人产生困惑的问题:为什么使用事件而不是委托变量,为什么通常委托的定义都返回void;第二部分讲述了如何处理异常和超时

2K20

C# WPF MVVM模式Prism框架下事件发布与订阅

01 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Prism提供了一种事件机制,可以应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事件进行通讯...简单来说就是提供了一个多播发布/订阅功能。Prism的事件聚合器,这玩意实现原理是观察者模式,观察者模式也就是常说的发布/订阅模式。...report; } } public class PersonInfoEven : PubSubEvent { } 03 订阅事件...,也可以在任何时候取消事件注册,只需要调用Unsubscribe方法即可 eventAggregator.GetEvent().Unsubscribe(ShowNews)...;//解除订阅 由于它是多播的,你可以在任意多个地方进行发布或订阅

2.9K20

C# WPF MVVM模式Caliburn.Micro框架下事件发布与订阅

01 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Caliburn提供了一种事件机制,可以应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事件进行通讯...简单来说就是提供了一个多播发布/订阅功能。Caliburn的事件聚合器,这玩意实现原理是观察者模式,观察者模式也就是常说的发布/订阅模式。...return report; } } public class PersonInfoEven : PersonInfo { } 03 订阅事件...//方式② Task.Run(action); }); } 这样,一个发布/订阅事件就完成了...,也可以在任何时候取消事件注册,只需要调用Unsubscribe方法即可 由于它是多播的,你可以在任意多个地方进行发布或订阅

1.8K10

.NET面试题系列 - 委托与事件

委托和事件 委托C#具有无比重要的地位。 C#的委托可以说俯拾即是,从LINQ的lambda表达式到(包括但不限于)winform,wpf的各种事件都有着委托的身影。...回调函数 回调函数是当一个函数运行完之后立即运行的另一个函数,这个函数需要之前函数的运行结果,所以不能简单的将他放在之前的函数的最后一句。回调函数C#问世之前就已经存在了。...相同签名的方法具有相同的类型,C#,这个特殊的类型有一个名字,就叫做委托。...,Invoke事件顺序激发所有订阅者的事件处理函数。...如果订阅事件的多个订阅事件触发时,有一个订阅者的事件处理函数引发了异常,则它将会影响后面的订阅者,后面的订阅者的事件处理函数不会运行。

1.1K20

RxJava2.X 源码分析(五):论切换线程次数的有效性

与Observer是如何发生订阅关系的 2、onNext、onComplete、onError被调用的次数限制及实现流程 3、onSubscribe方法为何第一个被调用?...及如何控制Disposable来取消订阅事件 4、分两篇分析了RxJava2.X切换订阅线程和观察者线程的源码 接下来我们将根据之前的分析成果从设计上分析RxJava2.X多次切换线程的有效性 具体分析...切换订阅事件线程的有效性 RxJava2.X 源码分析(三):探索RxJava2之订阅线程切换原理 我们分析了订阅线程切换的源码。...订阅事件的传递是从下往上传递,最终传递到上游被订阅者执行订阅流程 假设有三级,每级均发生线程切换: 下游Observer(订阅)->2级Observable(调用) 2级Observer(切换线程1订阅...根据RxJava的调用习惯也就是第一次,所以subscribeOn的调用只有第一次生效 切换观察者线程的有效性 我们RxJava2.X 源码分析(四)中分析了观察者事件线程切换的源码 订阅数据的数据流是从上而下下发的

42310

使用null条件运算符调用事件处理程序

但是实际上触发事件不是那么的简单,我们在这里考虑两个问题: 如果在程序根本没有任何一个处理程序和某个事件关联,会出现什么情况?...如果存在多个线程都要检测并调用同一个事件,这些线程之间又存在争夺的问题,会出现什么情况? 针对上面这两个问题, C# 6.0 中新增的 null 条件运算符就可以解决这个问题。...,如果对象触发 Updated事件时并没有相关的事件处理程序和它关联,这时就会出现 NullReferenceException 问题, C#6.0 出来之前如果要解决这个问题我们需要在每次触发前都要去判断以下事件处理程序是否为...) 语句时 B 线程将事件处理程序的订阅解除了,那么 A 线程执行到 Updated(this,count) 语句时事件处理程序已经为 null 了,这样仍然会出现 NullReferenceException...但是这里又有需要注意的地方,因为 C# 不允许 ?.

59820

Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus

来创建一个Subject对象(PublishSubject只有被订阅后才会把接收到的事件立刻发送给订阅者),需要接收事件的地方,订阅该Subject对象,之后如果Subject对象接收到事件,则会发射给该订阅者...完成了订阅需要发送事件的地方将事件发送给之前订阅的Subject对象,则此时Subject对象作为订阅者接收事件,然后会立刻将事件转发给订阅该Subject对象的订阅者,以便订阅者处理相应事件,到这里就完成了事件的发送与处理...最后就是取消订阅的操作了,RxJava订阅操作返回一个Subscription对象,以便在合适的时机取消订阅,防止内存泄漏,如果一个类产生多个Subscription对象,我们可以用一个CompositeSubscription...这个时候订阅者就会收到消息,并作相应的处理,非常简单。 问题出现 对于LiveDataBus的第一版实现,我们发现,使用这个LiveDataBus的过程订阅者会收到订阅之前发布的消息。...,这个订阅者立刻会收到一个回调,即使这个设置的动作发生订阅之前

2.3K30

C#之委托如此简单

近期和几位做嵌入式开发的朋友闲聊过程,一位朋友抱怨到:这C#太难用了,我想在N个窗体(或者是N个用户组件之间)传递值都搞不定,非得要定义一个全局变量来存储,然后用定时器来刷新值,太Low了。...此为这篇博客的起因,所以此篇博客对于有c#开发经验的伙伴们那是小菜一喋。...事件处理方法,需要判断是否为UI线程引发,如果不是,则需要委托来进行切换线程,代码见:private void EventBus_EventNotice(object sender, EventBusArg...传入了EventBus对象的实例,此实例与主界面的EventBus实例为同一个【这点很重要,发布和订阅事件必须在同一实例上】 2. button2_Click事件展示的是跨线程事件,执行此代码,主界面的刷新会走委托...事件订阅取消订阅,一般情况下可以关闭窗体时取消订阅 三、回顾 1. 事件依赖委托,事件可以订阅取消订阅,其订阅就是为事件增加委托。 2.

58710

Combine-Subscriber

Subscription 的request方法就体现了这种特性,它返回值是一个Subscribers.Demand,设置接受数据的最大值,但是每次收到新的数据以后都可以调整这个值,且这个值是累加的。...Subscriber 通过调用 2 创建的 Subscription 上的request(_: Demand)方法来首次告诉 Publisher 需要事件事件的最大值。...这里的 completion 可以是正常.finished,也可以是.failure的,如果是.failure的携带一个错误信息。注意:如果中途取消订阅,Publisher 将不发送完成事件。...4 Received value 5 Received value 6 Received completion finished */ 内置Subscriber Sink Assign Sink 闭包处理数据或...let subscription = downloadPublisher.sink { data in print("Received data: \(data)") } // 可以完成之前调用

95720

Godot3游戏引擎入门之八:添加可收集元素和子场景

创建很多的子场景: SKScene ,然后主游戏中加以重复利用。...,如果不明白怎么回事,又发生了金币不能被正常收集,那么你可以参考我之前的文章,使用 Godot 的碰撞体调试功能测试一下吧!...,观察者订阅事件源的某个事件,当事件发生了这个事件后,它并不需要知道谁订阅了它,只管把事件广播出去即可,然后那些订阅了这个事件的观察者们就能立刻侦听到这个事件,做出相应的处理,这就是所谓的观察者模式。... Godot 订阅事件或者信号叫 Connect 连接,信号发出后,连接了该信号的订阅者的相应函数会被调用,也就是成功处理了该事件,完成一个流程。如何使用 Signal 信号呢?...首先,我们为了不重复处理同一个事件,我们需要取消动画播放结束的信号。只需要在已连接好的信号下方,点击 Disconnect 按钮取消关联即可。 ? 其次,需要稍微修改消失动画。

1.8K30

如何开发一个简单好用的RxBus

因此尝试开发自己的RxBus之前,重点考虑下面两点: 支持粘性事件 这是非常重要的,因为有了粘性事件,我们可以解决activity/Fragment之间的消息传递,附带的好处是,进程内的数据传递,可以打破...PublishSubject:会把订阅发生的时间点之后来自原始Observable的数据发射给观察者 ? ReplaySubject: 会发射所有来自原始Observable的数据给观察者 ?...从上面的介绍可以看出,AsyncSubject显然不合适,PublishSubject看起来也不太合适,因为它不会发送订阅之前的消息,ReplaySubject和BehaviorSubject都能发送订阅之前的消息...显然是不太合理的,参考Intent,Activity,可以多次获取Intent,之后activity被销毁了,intent才会被销毁,因此,我们清除事件取消订阅的时候,也就是组件被销毁的时候。...框架帮你自动注册和注销。

1.2K30
领券