It is really cool, though it's still not clear whether C# directly or indirectly supports (probably not) defining a class in such a way which is pretty much a feature supposed to be seen in dynamic languages (not sure whether Java has it).
This feature not only saves time and writing of code, it also guarantees thread safety which is obviously the result of C# designer having taken into consideration the fact that this is the situation where most of delegated callbacks coded in this manner are supposed to be used.
Let's look at the following code snippet as an example:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AsyncCallOnDele { class Program { class AsyncCaller : IDisposable { List<Thread> _threads = new List<Thread>(); class ThreadUserData { public AsyncCallerCallback Callback; public object Arg; public ThreadUserData(AsyncCallerCallback callback, object arg) { Callback = callback; Arg = arg; } } public void ThreadProcedure(object arg) { ThreadUserData ud = (ThreadUserData)arg; ud.Callback(ud.Arg); } public void BeginInvoke(AsyncCallerCallback callback, object arg) { Thread thread = new Thread(new ParameterizedThreadStart(ThreadProcedure)); thread.Start(new ThreadUserData(callback, arg)); _threads.Add(thread); } public void Dispose() { foreach (Thread thread in _threads) thread.Join(); } } public delegate object AsyncCallerCallback(object o); class WorkData { public int Value; } static void Main(string[] args) { AsyncCaller cc = new AsyncCaller(); int count = 100; WorkData[] wdList = new WorkData[count]; using (AsyncCaller ac = new AsyncCaller()) { for (int i = 0; i < count; i++) { int localValue = i * 3; wdList[i] = new WorkData(); ac.BeginInvoke(o => { WorkData wd = (WorkData)o; lock (wdList) { Thread.Sleep(50); // a chance for 'localValue' to change wd.Value = localValue; } return null; }, wdList[i]); } } // here it waits until all threads complete within the Dispose method foreach (WorkData wd in wdList) { Console.WriteLine("{0} ", wd.Value); } } } }The output of the program is a list of integer values which are expected to be from 0 to 297 with a constant increment of 3 and they are.
I originally suspected they wouldn't give this result, an obvious influence by traditional C/C++ mindset. But after thinking about it again, I found it quite reasonable to have thing like this in C#, as such modern languages as C# and Java were designed to be as thread safe as they could.
So with this feature provided this way,the develop can focus their mind on the logic and designwithout worrying aboutisolating the variables accessed from the nested anonymous delegates in a multi-thread context.
本文探讨了C#中使用委托和lambda表达式的灵活性,特别是在多线程环境中确保线程安全的方法。通过一个具体的代码示例展示了如何利用这些特性来简化多线程编程,并保持代码的简洁性和可维护性。
2084

被折叠的 条评论
为什么被折叠?



