In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to understand .NET delegation". The content in the article is simple and clear, and it is easy to learn and understand. please follow the editor's train of thought to study and learn "how to understand .NET delegation".
Tight coupling
Once upon a time, in a strange land in the south, there was a worker named Peter. He was very diligent and was always obedient to his boss. But his boss is a stingy man who never trusts others and insists on keeping abreast of Peter's progress in order to prevent him from being lazy. But Peter didn't want his boss to stand behind him in his office and stare at him, so he promised his boss that I would let you know whenever I made any progress in my work. Peter fulfilled his promise by periodically using "typed references" ("typed reference", or delegate??) to "callback" his boss, as follows:
Class Worker {public void Advise (Boss boss) {_ boss = boss;} public void DoWork () {Console.WriteLine ("work: work begins"); if (_ boss! = null) _ boss.WorkStarted (); Console.WriteLine ("work: work in progress"); if (_ boss! = null) _ boss.WorkProgressing (); Console.WriteLine ("work: work done") If (_ boss! = null) {int grade = _ boss.WorkCompleted (); Console.WriteLine ("worker's work score =" + grade);}} private Boss _ boss;} class Boss {public void WorkStarted () {} public void WorkProgressing () {} public int WorkCompleted () {Console.WriteLine ("time is about 1); return 2 }} class Universe {static void Main () {Worker peter = new Worker (); Boss boss = new Boss (); peter.Advise (boss); peter.DoWork (); Console.WriteLine ("Main: worker's work done"); Console.ReadLine ();}}
Interface
Now, Peter is a special person who not only tolerates his stingy boss, but also has such a close connection with the universe around him that he thinks the universe is interested in his work progress. Unfortunately, he must also add a special callback function Advise to the universe to report work progress to both his boss and the universe. Peter wanted to separate the list of potential notifications from the implementation of those notifications, so he decided to separate the methods into an interface (these interfaces cause other problems that will be resolved by .NET delegates):
Interface IWorkerEvents {void WorkStarted (); void WorkProgressing (); int WorkCompleted ();} class Worker {public void Advise (IWorkerEvents events) {_ events = events;} public void DoWork () {Console.WriteLine ("work: work begins"); if (_ events! = null) _ events.WorkStarted (); Console.WriteLine ("work: work in Progress"); if (_ events! = null) _ events.WorkProgressing () Console.WriteLine ("work: work completed"); if (_ events! = null) {int grade = _ events.WorkCompleted (); Console.WriteLine ("worker's work score =" + grade);}} private IWorkerEvents _ events;} class Boss: IWorkerEvents {public void WorkStarted () {} public void WorkProgressing () {} public int WorkCompleted () {Console.WriteLine ("time is about 1); return 3 }}
.net delegation
Unfortunately, whenever Peter is busy communicating with his boss through the implementation of the interface, he doesn't have a chance to inform the universe in time. At least he should ignore the quotation from his boss who is far away so that other objects who have implemented IWorkerEvents can get his work report. (what does "At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress" mean? I don't understand what it means.)
His boss still complains a lot. Peter's boss roared, "Why are you bothering me at the beginning of my work and in the middle of it?" I don't care about these events. Not only are you forcing me to implement these methods, but you are also wasting my precious working time dealing with your affairs, especially when I am out! will you stop bothering me? "
As a result, Peter realized that while interfaces are useful in many cases, "granularity" is not good enough when used as events. He wanted to be able to notify others only when they wanted to, so he decided to separate the methods of the interface into separate delegates, each like a small interface method:
Delegate void WorkStarted (); delegate void WorkProgressing (); delegate int WorkCompleted (); class Worker {public void DoWork () {Console.WriteLine ("work begins"); if (started! = null) started (); Console.WriteLine ("work: work in Progress"); if (progressing! = null) progressing (); Console.WriteLine ("work: work done"); if (completed! = null) {int grade = completed () Console.WriteLine ("worker's work score =" + grade);}} public WorkStarted started; public WorkProgressing progressing; public WorkCompleted completed;} class Boss {public int WorkCompleted () {Console.WriteLine ("Better..."); return 4;}} class Universe {static void Main () {Worker peter = new Worker (); Boss boss = new Boss (); peter.completed = new WorkCompleted (boss.WorkCompleted); peter.DoWork () Console.WriteLine ("Main: worker's work done"); Console.ReadLine ();}}
Static listener
In this way, Peter won't bother his boss with events that his boss doesn't want, but he hasn't put the universe on his listener list yet. Because the universe is an all-inclusive entity, it does not seem appropriate to use the delegate of the instance method (imagine how many resources it takes to instantiate a "universe". .), so Peter needs to be able to hook static delegates, and delegates support this very well:
Class Universe {static void WorkerStartedWork () {Console.WriteLine ("Universe notices worker starting work");} static int WorkerCompletedWork () {Console.WriteLine ("Universe pleased with worker's work"); return 7;} static void Main () {Worker peter = new Worker (); Boss boss = new Boss (); peter.completed = new WorkCompleted (boss.WorkCompleted); peter.started = new WorkStarted (Universe.WorkerStartedWork); peter.completed = new WorkCompleted (Universe.WorkerCompletedWork) Peter.DoWork (); Console.WriteLine ("Main: worker's work done"); Console.ReadLine ();}}
Event
Unfortunately, the universe is too busy to keep an eye on the individuals in it. It can replace Peter's boss's commission with its own commission. This is an unconscious side effect of making the delegate field of Peter's Worker class public. Similarly, if Peter's boss gets impatient, he can decide to motivate Peter's commission himself (what a rude boss):
/ / Peter's boss taking matters into his own hands if (peter.completed! = null) peter.completed ()
Peter didn't want this to happen, and he realized that he needed to provide "registration" and "anti-registration" functions for each delegate so that listeners could add and remove delegates themselves, but at the same time they could not empty the entire list or trigger Peter's events at will. Instead of implementing these functions himself, Peter uses the event keyword to have the C # compiler build these methods for him:
Class Worker {... Public event WorkStarted started; public event WorkProgressing progressing; public event WorkCompleted completed;}
Peter knows that the event keyword wraps a property around the delegate, allowing only C # customers to add and remove through the + = and-= operators, forcing his boss and the universe to use events correctly.
Static void Main () {Worker peter = new Worker (); Boss boss = new Boss (); peter.completed + = new WorkCompleted (boss.WorkCompleted); peter.started + = new WorkStarted (Universe.WorkerStartedWork); peter.completed + = new WorkCompleted (Universe.WorkerCompletedWork); peter.DoWork (); Console.WriteLine ("Main: worker's work done"); Console.ReadLine ();}
"harvest" all the results
At this point, Peter can finally breathe a sigh of relief that he has successfully met the needs of all listeners while avoiding tight coupling with a particular implementation. But he noticed that both his boss and the universe rated its work, but he received only one score. In the face of multiple listeners, he wants to "harvest" all the results, so he goes deep into the agent, polls the listener list, and invokes them one by one:
Public void DoWork () {... Console.WriteLine ("work: work completed"); if (completed! = null) {foreach (WorkCompleted wc in completed.GetInvocationList ()) {int grade = wc (); Console.WriteLine ("worker's work score =" + grade);}
Asynchronous notification: activate & forget
At the same time, his boss and the universe were busy with other things, that is, the events they spent grading Peter became very long:
Class Boss {public int WorkCompleted () {System.Threading.Thread.Sleep (3000); Console.WriteLine ("Better..."); return 6;} class Universe {static int WorkerCompletedWork () {System.Threading.Thread.Sleep (4000); Console.WriteLine ("Universe is pleased with worker's work"); return 7;}.}
Unfortunately, every time Peter notifies a listener, he has to wait for it to grade himself, and now these notifications cost him too much work. So he decided to forget the score and just trigger the event asynchronously:
Public void DoWork () {... Console.WriteLine ("work: work done"); if (completed! = null) {foreach (WorkCompleted wc in completed.GetInvocationList ()) {wc.BeginInvoke (null, null);}
Asynchronous notification: polling
This allows Peter to notify his listener and then return to work immediately, allowing the process's thread pool to call these agents. As time went by, Peter found that he had lost feedback on his work. He knew that listening to other people's praise was as important as hard work, so he triggered events asynchronously, but polled periodically to get available scores.
Public void DoWork () {... Console.WriteLine ("work: work completed"); if (completed! = null) {foreach (WorkCompleted wc in completed.GetInvocationList ()) {IAsyncResult res = wc.BeginInvoke (null, null); while (! res.IsCompleted) System.Threading.Thread.Sleep (1); int grade = wc.EndInvoke (res); Console.WriteLine ("worker's job score =" + grade);}
Asynchronous notification: .net delegate
Unfortunately, Peter went back to the situation he wanted to avoid in the first place, such as the boss standing behind his back and staring at him at work. So he decided to use his own delegate as a notification of the completion of the asynchronous delegate he called, allowing himself to go back to work immediately, but he could still be notified after his work had been graded:
Public void DoWork () {... Console.WriteLine ("work: work completed"); if (completed! = null) {foreach (WorkCompleted wc in completed.GetInvocationList ()) {wc.BeginInvoke (new AsyncCallback (WorkGraded), wc);} private void WorkGraded (IAsyncResult res) {WorkCompleted wc = (WorkCompleted) res.AsyncState; int grade = wc.EndInvoke (res); Console.WriteLine ("worker's work score =" + grade) } Thank you for your reading. the above is the content of "how to understand .NET delegation". After the study of this article, I believe you have a deeper understanding of how to understand .NET delegation, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.