1 class Program 2 { 3 static void Main(string[] args) 4 { 5 DelegateIntro.Go(); 6 Console.ReadKey(); 7 } 8 } 9 10 11 internal sealed class DelegateIntro 12 { 13 //声明一个委托类型,它的实例引用一个方法, 14 // 该方法获取一个Int32参数,返回void 15 //创建一个Feedback类(包含4个方法,构造方法,Invoke,BeginInvoke,EndInvoke),派生自MulticastDelegate。 16 internal delegate void Feedback(Int32 value); 17 18 public static void Go() 19 { 20 StaticDelegateDemo(); 21 InstanceDelegateDemo(); 22 ChainDelegateDemo1(new DelegateIntro()); 23 ChainDelegateDemo2(new DelegateIntro()); 24 } 25 26 private static void StaticDelegateDemo() 27 { 28 Console.WriteLine("----- Static Delegate Demo -----"); 29 Counter(1, 3, null); 30 Counter(1, 3, new Feedback(DelegateIntro.FeedbackToConsole)); 31 Counter(1, 3, new Feedback(FeedbackToMsgBox)); // "Program." is optional 32 Console.WriteLine(); 33 } 34 35 private static void InstanceDelegateDemo() 36 { 37 Console.WriteLine("----- Instance Delegate Demo -----"); 38 DelegateIntro di = new DelegateIntro(); 39 40 Counter(1, 3, new Feedback(di.FeedbackToFile)); 41 Feedback f1 = di.FeedbackToFile; 42 43 Console.WriteLine(); 44 } 45 46 private static void ChainDelegateDemo1(DelegateIntro di) 47 { 48 Console.WriteLine("----- Chain Delegate Demo 1 -----"); 49 Feedback fb1 = new Feedback(FeedbackToConsole); 50 Feedback fb2 = new Feedback(FeedbackToMsgBox); 51 Feedback fb3 = new Feedback(di.FeedbackToFile); 52 53 Feedback fbChain = null; 54 fbChain = (Feedback)Delegate.Combine(fbChain, fb1); 55 fbChain = (Feedback)Delegate.Combine(fbChain, fb2); 56 fbChain = (Feedback)Delegate.Combine(fbChain, fb3); 57 Counter(1, 2, fbChain); 58 59 Console.WriteLine(); 60 fbChain = (Feedback)Delegate.Remove(fbChain, new Feedback(FeedbackToMsgBox)); 61 Counter(1, 2, fbChain); 62 } 63 64 65 private static void ChainDelegateDemo2(DelegateIntro di) 66 { 67 Console.WriteLine("----- Chain Delegate Demo 2 -----"); 68 Feedback fb1 = new Feedback(FeedbackToConsole); 69 Feedback fb2 = new Feedback(FeedbackToMsgBox); 70 Feedback fb3 = new Feedback(di.FeedbackToFile); 71 72 Feedback fbChain = null; 73 fbChain += fb1; 74 fbChain += fb2; 75 fbChain += fb3; 76 Counter(1, 2, fbChain); 77 78 Console.WriteLine(); 79 fbChain -= new Feedback(FeedbackToMsgBox); 80 Counter(1, 2, fbChain); 81 } 82 83 private static void Counter(Int32 from, Int32 to, Feedback fb) 84 { 85 for (Int32 val = from; val <= to; val++) 86 { 87 // If any callbacks are specified, call them 88 if (fb != null) 89 fb(val); 90 } 91 } 92 93 private static void FeedbackToConsole(Int32 value) 94 { 95 Console.WriteLine("ItemC=" + value); 96 } 97 98 private static void FeedbackToMsgBox(Int32 value) 99 { 100 Console.WriteLine("ItemB=" + value); 101 } 102 103 private void FeedbackToFile(Int32 value) 104 { 105 StreamWriter sw = new StreamWriter("Status", true); 106 sw.WriteLine("Item=S" + value); 107 sw.Close(); 108 } 109 } 110 111 112 113 #region 显示调用委托链 114 internal static class GetInvocationList 115 { 116 // Define a Light component. 117 internal sealed class Light 118 { 119 // This method returns the light's status. 120 public String SwitchPosition() 121 { 122 return "The light is off"; 123 } 124 } 125 126 // Define a Fan component. 127 internal sealed class Fan 128 { 129 // This method returns the fan's status. 130 public String Speed() 131 { 132 throw new InvalidOperationException("The fan broke due to overheating"); 133 } 134 } 135 136 // Define a Speaker component. 137 internal sealed class Speaker 138 { 139 // This method returns the speaker's status. 140 public String Volume() 141 { 142 return "The volume is loud"; 143 } 144 } 145 146 // Definition of delegate that allows querying a component's status. 147 private delegate String GetStatus(); 148 149 public static void Go() 150 { 151 // Declare(声明) an empty delegate chain. 152 GetStatus getStatus = null; 153 154 // Construct the three components, and add their status methods 155 // to the delegate chain. 156 getStatus += new GetStatus(new Light().SwitchPosition); 157 getStatus += new GetStatus(new Fan().Speed); 158 getStatus += new GetStatus(new Speaker().Volume); 159 160 // Show consolidated status report reflecting 161 // the condition of the three components. 162 Console.WriteLine(GetComponentStatusReport(getStatus)); 163 } 164 165 // Method that queries several components and returns a status report 166 private static String GetComponentStatusReport(GetStatus status) 167 { 168 169 // If the chain is empty, there抯 is nothing to do. 170 if (status == null) return null; 171 172 // Use this to build the status report. 173 StringBuilder report = new StringBuilder(); 174 175 // Get an array where each element is a delegate from the chain. 176 Delegate[] arrayOfDelegates = status.GetInvocationList(); 177 178 // Iterate over each delegate in the array. 179 foreach (GetStatus getStatus in arrayOfDelegates) 180 { 181 182 try 183 { 184 // Get a component's status string, and append it to the report. 185 report.AppendFormat("{0}{1}{1}", getStatus(), Environment.NewLine); 186 } 187 catch (InvalidOperationException e) 188 { 189 190 // Generate an error entry in the report for this component. 191 Object component = getStatus.Target; 192 report.AppendFormat( 193 "Failed to get status from {1}{2}{0} Error: {3}{0}{0}", 194 Environment.NewLine, 195 ((component == null) ? "" : component.GetType() + "."), 196 getStatus.Method.Name, e.Message); 197 } 198 } 199 200 // Return the consolidated report to the caller. 201 return report.ToString(); 202 } 203 } 204 #endregion 205 206 #region 局部变量不需要手动包装到类中传给回掉函数 207 sealed class AClass2 208 { 209 private static void UsingLocalVariablesInTheCallbackCode(Int32 numToDo) 210 { 211 212 // Some local variables 213 Int32[] squares = new Int32[numToDo]; 214 AutoResetEvent done = new AutoResetEvent(false); 215 216 // Do a bunch of tasks on other threads 217 for (Int32 n = 0; n < squares.Length; n++) 218 { 219 ThreadPool.QueueUserWorkItem( 220 delegate (Object obj) 221 { 222 Int32 num = (Int32)obj; 223 224 // This task would normally more time consuming 225 squares[num] = num * num; 226 227 // If last task, let main thread continue running 228 if (Interlocked.Decrement(ref numToDo) == 0) 229 done.Set(); 230 }, n); 231 } 232 233 // Wait for all the other threads to finish 234 done.WaitOne(); 235 236 // Show the results 237 for (Int32 n = 0; n < squares.Length; n++) 238 Console.WriteLine("Index {0}, Square={1}", n, squares[n]); 239 } 240 } 241 #endregion