When C# Anonymous Method is Asynchronously Invoked

本文探讨了C#中使用委托和lambda表达式的灵活性,特别是在多线程环境中确保线程安全的方法。通过一个具体的代码示例展示了如何利用这些特性来简化多线程编程,并保持代码的简洁性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C# is pretty flexible in syntax which by means of working with delegate or lambda expressionallows one to define subroutine logic within the argument list of a method call where it is passed.

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值