1 00:00:07,230 --> 00:00:07,680 Hello. 2 00:00:08,640 --> 00:00:16,620 In this lecture, we're going to talk about Question 43, what our events and event is a message sent 3 00:00:16,620 --> 00:00:20,280 by an object to signal the occurrence of an action. 4 00:00:20,790 --> 00:00:25,540 Events are the dots, nuts, implementation of the observer design pattern. 5 00:00:26,160 --> 00:00:31,440 Let's implement the same logic we had in the lecture about the observatory's own pattern. 6 00:00:31,800 --> 00:00:38,730 We want the Bitcoin price reader object to notify other objects about the reading of the bitcoin price. 7 00:00:39,210 --> 00:00:42,030 This time will do so using events. 8 00:00:42,570 --> 00:00:49,400 We'll start by defining a delegate that will represent the function or functions that will be executed 9 00:00:49,410 --> 00:00:52,230 once the price reading event has been raised. 10 00:01:00,120 --> 00:01:05,070 The Bitcoin price reader will own an event of these delegates type. 11 00:01:11,200 --> 00:01:15,070 Let's take a moment to stop and think about what happened here. 12 00:01:15,490 --> 00:01:22,800 We declared an event belonging to the bitcoin price rigging across an event is always over delegates. 13 00:01:22,840 --> 00:01:31,760 I remember a delegate is a type whose instances hold a reference to admit it or methods with particular 14 00:01:31,780 --> 00:01:38,200 parameters released and return type would never start in this field would be a method or methods. 15 00:01:38,290 --> 00:01:44,710 Taking this email as a parameter and returning nothing as we declared it staggered as void. 16 00:01:45,370 --> 00:01:51,490 So what is the difference between an event and a regular field of a delegate type? 17 00:01:51,820 --> 00:01:55,570 In other words, what would be the difference between those two? 18 00:01:59,170 --> 00:02:04,360 Both seem like fields of a delegated type, but this isn't the event. 19 00:02:04,870 --> 00:02:07,840 Let's try to attach some method to both of them. 20 00:02:25,330 --> 00:02:32,650 So far, an event in the field of delegates type act exactly the same, but here is the difference. 21 00:02:40,040 --> 00:02:45,000 As you can see, I can't invoke the event from outside of the class. 22 00:02:45,020 --> 00:02:50,660 It belongs to I can invoke the non event delegate without a problem. 23 00:02:51,380 --> 00:02:53,160 This is a critical difference. 24 00:02:53,420 --> 00:02:56,750 Only the class that owns an event can raise it. 25 00:02:57,140 --> 00:03:00,950 Events are used to send notifications about some action. 26 00:03:01,250 --> 00:03:08,120 So imagine what would happen if any grass could raise them and the code could raise the price red event 27 00:03:08,240 --> 00:03:13,670 with the price it wants, triggering invite notifications all around the system. 28 00:03:14,210 --> 00:03:21,620 The event delegate must be public so the subscribers can subscribe to it, but it must only be invaluable 29 00:03:21,710 --> 00:03:24,050 from within the class that owns it. 30 00:03:24,410 --> 00:03:27,290 And that's what the event keyword enforces. 31 00:03:28,250 --> 00:03:28,960 All right. 32 00:03:29,450 --> 00:03:31,430 Let's move on with the implementation. 33 00:03:31,730 --> 00:03:37,460 We defined an event in the bitcoin price reader class when the bitcoin price is red. 34 00:03:37,850 --> 00:03:39,650 We want to raise that event. 35 00:03:39,830 --> 00:03:44,000 So simply invoke all methods stored in the event dugout. 36 00:03:44,390 --> 00:03:48,980 This means all subscribers will be notified that the event occured. 37 00:04:05,650 --> 00:04:09,930 As you can see, I executed the event delegate by the Invoke method. 38 00:04:10,360 --> 00:04:12,070 Let me show you why I did it. 39 00:04:15,970 --> 00:04:19,210 This is a standard way of invoking a delegate. 40 00:04:19,480 --> 00:04:26,440 But price, what event will be known before and this subscriber subscribes to it in this case, here 41 00:04:26,440 --> 00:04:28,660 I will get another reference exception. 42 00:04:28,960 --> 00:04:34,510 I wanted to use the new air conditioner operator, which will only execute this delegate if it's not 43 00:04:34,510 --> 00:04:34,900 new. 44 00:04:35,140 --> 00:04:39,460 But if I try to use it like this, it won't compile. 45 00:04:39,790 --> 00:04:42,220 It's not possible to use this operator like this. 46 00:04:42,550 --> 00:04:47,530 That's why, instead of simply calling this delegate, I used the Invoke method. 47 00:04:47,770 --> 00:04:53,740 The result will be the same, so the delegate will be invoked, but I am able to use the normal conditional 48 00:04:53,740 --> 00:04:57,010 operator to make sure no exception will be thrown. 49 00:04:58,930 --> 00:04:59,620 All right. 50 00:04:59,830 --> 00:05:02,380 Let's summarize what happened in this class. 51 00:05:02,710 --> 00:05:08,020 We declared an event which is of a delegate type when the bitcoin price is red. 52 00:05:08,140 --> 00:05:12,130 We want to raise the event so all subscribers are notified. 53 00:05:12,610 --> 00:05:14,530 Let's move on to the subscribers. 54 00:05:15,010 --> 00:05:20,560 Each subscriber must contain a method that is compatible with the event delegate. 55 00:05:20,860 --> 00:05:24,280 In our case, avoid method accepting this email. 56 00:05:24,580 --> 00:05:28,660 Luckily, we currently have such method in the notifier class. 57 00:05:29,320 --> 00:05:35,380 Now we can subscribe, then notify classes to the Bitcoin price with our class so they are notified 58 00:05:35,380 --> 00:05:37,030 when the event is raised. 59 00:05:46,750 --> 00:05:47,920 And that's it. 60 00:05:48,310 --> 00:05:51,970 All that's left to do is to call the current price method. 61 00:05:55,720 --> 00:05:57,940 It seems like everything is working. 62 00:05:58,330 --> 00:06:03,760 Let's see again what happened when the right current price method is executed. 63 00:06:03,970 --> 00:06:05,110 This is what happens. 64 00:06:05,680 --> 00:06:10,210 It reads the current price and it raises the price for that event. 65 00:06:10,660 --> 00:06:17,590 The price great event is invoked and since the update method from IMO price tend to notifier and push 66 00:06:17,590 --> 00:06:21,130 price trends, Notifier are attached to the event delegate. 67 00:06:21,310 --> 00:06:22,480 They get executed. 68 00:06:23,230 --> 00:06:29,370 So, for example, this is a method that is attached to this event handler. 69 00:06:30,460 --> 00:06:31,120 All right. 70 00:06:31,330 --> 00:06:33,200 Everything works as expected. 71 00:06:33,640 --> 00:06:40,570 There is one improvement we can make, though instead of having our own price delegates for the event, 72 00:06:40,780 --> 00:06:45,220 we can use the event handler or delegate that is predefined in C-sharp. 73 00:06:48,030 --> 00:06:55,260 This is the signature of this delegate, as you can see, it carries the information about the object 74 00:06:55,260 --> 00:07:02,670 that raised that event and event arguments, even arcs is a base class for other event arguments we 75 00:07:02,670 --> 00:07:03,120 want. 76 00:07:03,360 --> 00:07:07,980 In our case, the argument of an event is the bitcoin price that has been. 77 00:07:09,030 --> 00:07:12,840 Let's create our own type derived from event arcs. 78 00:07:25,140 --> 00:07:31,410 To make sure this type of event argument will be used, we must use the generic event handler. 79 00:07:34,500 --> 00:07:42,090 We must now turn to the cold that raises that event to mark the event handler of price event asks delegates 80 00:07:42,090 --> 00:07:42,570 type. 81 00:07:47,680 --> 00:07:51,560 As you can see us, the first argument we pass this. 82 00:07:51,610 --> 00:07:59,230 So the center of the event, the second argument is that price read event arcs object holding the price. 83 00:07:59,950 --> 00:08:05,800 The last thing left to do is to change the update method in the price point and the different classes. 84 00:08:22,250 --> 00:08:22,950 All right. 85 00:08:23,390 --> 00:08:25,160 Let's make sure everything works. 86 00:08:27,660 --> 00:08:29,610 Looking exactly as before. 87 00:08:31,640 --> 00:08:38,030 You may think that this is more complicated than the cold that we had before, and this is true. 88 00:08:38,630 --> 00:08:46,430 Nevertheless, I wanted to show you this event handler type as it is used in many Microsoft's frameworks 89 00:08:46,430 --> 00:08:54,560 based on events, for example in Windows Forums or Windows Presentation Foundation, desktop applications 90 00:08:54,710 --> 00:09:02,360 or user actions like clicking on a button or closing a window trigger events and those events are defined 91 00:09:02,420 --> 00:09:02,630 well. 92 00:09:02,630 --> 00:09:04,190 The event handler delegate. 93 00:09:04,550 --> 00:09:11,600 In those use cases, the sender argument is used by the subscribers, which we did not need to do in 94 00:09:11,600 --> 00:09:12,560 our code. 95 00:09:13,190 --> 00:09:20,270 One last thing before we wrap up, this is generally a good practice to unsubscribe from the event handler 96 00:09:20,300 --> 00:09:24,470 before the object getting notified about the event is discarded. 97 00:09:29,840 --> 00:09:36,470 I don't want to get into details about why it is important, as this lecture is quite long already. 98 00:09:36,740 --> 00:09:39,290 So let me just give you a very quick overview. 99 00:09:39,800 --> 00:09:46,640 When a subscriber subscribes to be notified about a state turned in, some object actually then reference 100 00:09:46,640 --> 00:09:48,230 is created between them. 101 00:09:48,620 --> 00:09:54,770 It is needed because the event handler holds a reference to a method stored in the object that will 102 00:09:54,770 --> 00:09:56,450 be notified about the event. 103 00:09:56,660 --> 00:09:59,150 So our reference to this object is necessary. 104 00:09:59,780 --> 00:10:07,430 It may happen that we think an object is no longer in use while the garbage collector still sees a reference 105 00:10:07,430 --> 00:10:10,010 to it and will not remove it from memory. 106 00:10:10,370 --> 00:10:17,030 For example, consider a desktop application with some a main window and a third window that opens when 107 00:10:17,030 --> 00:10:18,410 you click some button. 108 00:10:18,740 --> 00:10:25,190 The child window is subscribed to an event of the main window, so the reference from the main window 109 00:10:25,190 --> 00:10:29,120 to third window exists when we close the child window. 110 00:10:29,150 --> 00:10:35,330 It should be removed from memory, but the garbage collector will see this reference and will decide 111 00:10:35,330 --> 00:10:42,350 this object should not be removed as the applications user keeps opening and closing child windows. 112 00:10:42,500 --> 00:10:47,210 More and more memory is being used, but none of it is being freed. 113 00:10:47,720 --> 00:10:50,300 This situation is called a memory leak. 114 00:10:50,540 --> 00:10:57,050 Over time, it may slow the application down or even cause it to crash due to out of memory exception 115 00:10:57,410 --> 00:11:00,170 unsubscribing from events when it's possible. 116 00:11:00,380 --> 00:11:05,300 For example, when the third window is being closed, it's a way of preventing that. 117 00:11:05,930 --> 00:11:12,110 Let's summarize events are the ultimate way of implementing the observer design pattern. 118 00:11:12,620 --> 00:11:18,110 They are used to send a notification from an object to all objects subscribed. 119 00:11:18,680 --> 00:11:23,810 The pattern of using events is as follows The class that we will be sending. 120 00:11:23,810 --> 00:11:31,520 Notifications owns an event which is another great object that wants to be notified about an event can 121 00:11:31,520 --> 00:11:34,310 attach their own methods to this delegate. 122 00:11:34,770 --> 00:11:41,870 When the Observer Bluegrass raises the event, it does so by invoking the methods stored in the delegate. 123 00:11:42,260 --> 00:11:48,320 This way, all methods from the observers are being executed during the interview. 124 00:11:48,350 --> 00:11:54,230 You can be asked What is the difference between an event and the field of the delegate type? 125 00:11:54,620 --> 00:11:59,840 A public field of a delegate type can be invoked from anywhere in the cold. 126 00:12:00,260 --> 00:12:04,070 Events can only be invoked from the class they belong to. 127 00:12:04,820 --> 00:12:11,510 Why is it a good practice to unsubscribe from events when a subscribed object is no longer needed? 128 00:12:12,050 --> 00:12:18,740 Because as long as it is subscribed, a hidden reference between the observer and the observer exists, 129 00:12:19,100 --> 00:12:24,590 and it will prevent the garbage collector from removing the observer object from memory. 130 00:12:25,280 --> 00:12:26,000 All right. 131 00:12:26,420 --> 00:12:31,880 This has been a long lecture, but I believe we covered the pretty complex topic of events. 132 00:12:32,210 --> 00:12:35,810 Thanks for following along, and I see you in the next lecture.