no great desire, no great genius--aaronyang's blog (www.ayjs.net)-www.8mi.me
1. Events-My Lectures
The teacher often tells me that events are special delegates that provide a publish/subscribe mechanism for delegates.
- Custom events: Customizing a Class, inheriting EventArgs
- Use generic delegate eventhandler<t>, nature: public delegate void Eventhandler<teventargs> (Object Sender,teventargs e) where Teventhandlers:eventargs
- Defines the simple notation for events public event eventhandler<teventargs> MyEvent; here eventhandler<teventargs> refers to a method signature in accordance with 2, void , with two parameters, the first sender parameter contains the sender of the event. The second parameter provides information about the event. Because this event can be customized, it can bring a lot of rich information, but also can use the system comes with.
- Add or remove handlers (events) for a delegate using the Add and remove in the event properties, or you can use + = or-= Processing yourself
- Using Events
1.1 Let's write a simple example that will allow you to understand this knowledge.
Requirement: I need the user to use the class I provide, it might be a DLL, and in my class, I can define the details of the event. For example: Blog events, there are 1 new articles, there may be readers to read blogs, some people use computers, some people use mobile phones, some people use the Kindle
Design:
The first step: custom events, the advantage is that you can provide other object values when the event is triggered
Public classBlogeventargs:eventargs {/// <summary> ///Blog Title/// </summary> /// <param name= "title" ></param> PublicBlogeventargs (stringtitle) { This. Title =title; } //Blog Title Public stringTitle {Get;Set; } }
Step two: Define events to make it easier for users to add their own defined events, delete their own defined events, and a way to invoke user-bound events (special delegates)
Public classBlogeventprovider {/// <summary> ///First step: Define an event and encapsulate it to bind the event to the user/// </summary> Private EventEventhandler<blogeventargs>blogevents; Public EventEventhandler<blogeventargs>blogevents {add {blogevents+=value; } Remove {blogevents-=value; } } //triggers the user-bound event, or adds some processing before the event, and then triggers Public voidPreviewreadblog (stringtitle) {Console.WriteLine ("getting the contents of the blog ' {0} ' ...", title); Onreadblog (title); } protected Virtual voidOnreadblog (stringtitle) { if(Blogevents! =NULL) {blogevents ( This,NewBlogeventargs (title)); } } }
Step three: Define a blog-supported device enumeration
/// <summary> /// supported devices for blog posts /// </summary> Public enum Blogsupportdevice { PC, Kindle, Mobile }
Fourth step: Define the people who read the blog, of course, the implementation of the event here can also be written elsewhere.
/// <summary> ///Blog Reader/// </summary> Public classBlogreader { PublicBlogreader (stringreadername, Blogsupportdevice device) { This. Readername =Readername; This. Device =device; } Public stringReadername {Get;Set; } PublicBlogsupportdevice Device {Get;Set; } /// <summary> ///because you need to know the title of the blog There are other details, so customized a Blogeventargs class/// </summary> /// <param name= "Sender" ></param> /// <param name= "E" ></param> Public voidOnreadblog (ObjectSender,blogeventargs e) {Console.WriteLine ("{ 3}:{0} read ' {2} ' using {1}", Readername,device.tostring (), E.title,datetime.now.tolocaltime ()); } }
Fifth Step: Use
The sixth step: expansion and reflection
1. If I bind n times the same event, and then execute the event, will it only fire 1 times, or does it trigger n times?
Answer: is n times, this is also the title of the last article left, the delegate is bound more than the same method will be executed multiple times?
2. Complete the fifth step code, use-= To remove the previous event, or execute the event when it is executed more than once because the event is a special delegate with the attributes of the multicast delegate.
Static voidMain (string[] args) { //defines the event providerBlogeventprovider Provider =NewBlogeventprovider (); //Define a blog reading personBlogreader ay =NewBlogreader ("Little Aaronyang", blogsupportdevice.pc); //ay begins to bind its own defined event, and the event provider adds some action before triggering the event, rather than letting the user do it himself.Provider. Blogevents + =ay. Onreadblog; //Start Reading BlogProvider. Previewreadblog ("[Aaronyang] write to own WPF4.5 Note [2 dependency properties]"); Provider. Blogevents-= ay. Onreadblog;//Remove ay reader//Define a blog reading personBlogreader yy =NewBlogreader ("Yang Yang", Blogsupportdevice.kindle); //ay begins to bind its own defined event, and the event provider adds some action before triggering the event, rather than letting the user do it himself.Provider. Blogevents + =yy. Onreadblog; //start readingProvider. Previewreadblog ("[Aaronyang] write to own WPF4.5 notes [1 layouts]"); Console.ReadLine (); }
:
2. The event is not complex, just like JS in the method as a parameter passed, such as function A (b,d) {B ()}
Here B is a method, people call a when you can customize a B, and B is just a function object, with a few parameters, in the parameters of a functions are not reflected, but in the invocation of B is reflected. Assuming a B function has 2 parameters (x, y), then
function A (b,d) {var e=b (1,3)}
function Cusb (x, y) {return x*y}
A (CUSB, ' Custom ')
Frankly, it feels a bit like leaving an event interface to the user
===============aaronyang========www.8mi.me================== 2. Weak events-Introduction
Understanding the release and subscription models of events-publisher and listener
Aaronyang: Publisher is where the event is defined, as in the example above is the Blogeventprovider class, which defines the private event eventhandler<blogeventargs> blogevents;
And listener is the place to add or remove specific event implementations for this event. As the example above is the Blogreader class, it has a method signature that blogevents conforms to the event (blogevents). So you can normally use + = and-= entrusted to the east.
OK, let's test why we need a weak event. The right thing to do is to prevent memory leaks from events.
Next, we add a garbage collection method to the program class to facilitate testing
Static void TRIGGERGC () { Console.WriteLine ("starting GC. " ); Gc. Collect (); Gc. WaitForPendingFinalizers (); Gc. Collect (); Console.WriteLine ("GC finished. " );
The first GC. Collect () The CLR garbage collector that triggers. NET, the CLR garbage collector is adequate for objects that are not used for cleanup, and those that do not have finalizers (that is, destructors in C #) in those classes
Gc. WaitForPendingFinalizers () waits for the finalizer of other objects to execute;
The second gc.collect () ensures that the newly-formed objects are also cleared.
Next, let's go on to the last example, and the fifth step of the code assumes you have one.
We now empty the Ay object, then let garbage reclaim the Ay object, and then we execute the event
Static voidMain (string[] args) { //defines the event providerBlogeventprovider Provider =NewBlogeventprovider (); //Define a blog reading personBlogreader ay =NewBlogreader ("Little Aaronyang", blogsupportdevice.pc); //ay begins to bind its own defined event, and the event provider adds some action before triggering the event, rather than letting the user do it himself.Provider. Blogevents + =ay. Onreadblog; //Start Reading BlogProvider. Previewreadblog ("[Aaronyang] write to own WPF4.5 Note [2 dependency properties]"); //provider. Blogevents-= ay. Onreadblog;//Remove ay reader ////define Blog reading people //Blogreader yy = new Blogreader ("Yang Yang", blogsupportdevice.kindle); ////ay begins to bind its own defined events, and the event provider adds some action before triggering the event, rather than letting the user do it himself. //provider. Blogevents + = yy. Onreadblog; ////Start reading //provider. Previewreadblog ("[Aaronyang] wrote to own WPF4.5 notes [1 Layout]"); //strong references to test events ayay =NULL; TRIGGERGC (); Provider. Previewreadblog ("[Aaronyang] write to his own WPF4.5 notes [3 Advanced events]"); Console.ReadLine (); }
Results:
The result was surprised to find that the event could be executed! This means that the Ay object is still there, this is a strong reference, so a lot of C # write code after the execution of the event, then go on to write other code, and no matter whether garbage collection can be recycled, causing a memory leak problem.
Next, we add a destructor to the Blogeventprovider to confirm that the Blogeventprovider object is actually recycled
~Blogeventprovider () { Console.WriteLine ("Blogeventprovider's destructor is executed " ) ); }
OK, we'll add the code to the program's Main method:
NULL ; TRIGGERGC ();
Effect:
OK, I'm sure the Ay object is released at this time. Of course, not necessarily to release the Ay object to reclaim memory Ah, the memory leak of the event, you just have to + +, after execution, manually go to-= event on the line. In this way, the garbage collector can automatically recycle the Ay object in the background, otherwise, you have been using the provider object, garbage collection can never be recycled ay, assuming that the event in provider is bound to a lot of event implementation, and these implementations, you executed, but did not do the-=, Then it can lead to the problem of leakage, of course, the memory is high-occupancy problem. Well, if you want to new a provider, that scrap, then you new too much, you will have a lot of memory, and if you do not have a manual GC, the memory consumption is more scary.
Provider. blogevents -= ay. Onreadblog; NULL ; TRIGGERGC (); Provider. Previewreadblog ("[Aaronyang] to own WPF4.5 notes [3 Advanced events]");
So how do you solve this problem? net4.5 provides a more straightforward approach to weak references, of course, 4.5 of other ways that have weak references, of course, are more complex, and are not spoken here, only 4.5 of the way.
3. Weak event-aaronyang
If you use a generic pattern of 4.5, it's super-simple, and you don't have to inherit Weakeventmanager,iweakeventlistener anymore. MSDN Location: View
And no longer have to worry about binding multiple times the same event, executed multiple times
We use
" blogevents "ay. Onreadblog);
Instead of just
Provider. Blogevents + = ay. Onreadblog;
Premise: you want to introduce WindowsBase.dll
Static voidMain (string[] args) { //defines the event providerBlogeventprovider Provider =NewBlogeventprovider (); //Define a blog reading personBlogreader ay =NewBlogreader ("Little Aaronyang", blogsupportdevice.pc); //ay begins to bind its own defined event, and the event provider adds some action before triggering the event, rather than letting the user do it himself.//provider. Blogevents + = ay. Onreadblog;System.windows.weakeventmanager<blogeventprovider, Blogeventargs> AddHandler (provider,"blogevents", Ay. Onreadblog); //test binding multiple times and only once//System.windows.weakeventmanager<blogeventprovider, Blogeventargs> AddHandler (provider, "blogevents", Ay. Onreadblog); //Start Reading BlogProvider. Previewreadblog ("[Aaronyang] write to own WPF4.5 Note [2 dependency properties]"); Ay=NULL; TRIGGERGC (); Provider. Previewreadblog ("[Aaronyang] write to his own WPF4.5 notes [3 Advanced events]"); Console.ReadLine (); }
Effect:
When the second execution event was found, Ay had been released. True TM!!
====== Anhui Liuan =========www.ayjs.net==========aaronyang======== Yang Yang ========www.8mi.me==========
[Aaronyang] C # People love to learn not to learn 8[events and. net4.5 's weak events in layman's light]