using System; delegate void WorkStarted(); delegate void WorkProgressing(); delegate int WorkCompleted(); class Worker { public event WorkStarted Started; public event WorkProgressing Progressing; public event WorkCompleted Completed; public void DoWork() { Console.WriteLine("Worker: work started"); if( this.Started != null ) this.Started(); Console.WriteLine("Worker: work progressing"); if( this.Progressing != null ) this.Progressing(); Console.WriteLine("Worker: work completed"); if( this.Completed != null ) { foreach( WorkCompleted wc in this.Completed.GetInvocationList() ) { // Create an unchanging variable referencing the current wc WorkCompleted wc2 = wc; wc.BeginInvoke(delegate(IAsyncResult result) { // Use wc2 variable from surrounding context int grade = wc2.EndInvoke(result); Console.WriteLine("Worker grade= {0}", grade); }, null); } } } } class Boss { public int WorkCompleted() { System.Threading.Thread.Sleep(5000); Console.WriteLine("It's about time!"); return 4; // out of 10 } } class Universe { static void WorkerStartedWork() { Console.WriteLine("Universe notices worker starting work"); } static int WorkerCompletedWork() { System.Threading.Thread.Sleep(10000); Console.WriteLine("Universe pleased with worker's work"); return 7; } static void Main() { Worker peter = new Worker(); Boss boss = new Boss(); //peter.Completed = boss.WorkCompleted; peter.Completed += boss.WorkCompleted; peter.Started += Universe.WorkerStartedWork; peter.Completed += Universe.WorkerCompletedWork; peter.DoWork(); Console.WriteLine("Main: worker completed work"); Console.ReadLine(); } }