.net5 core webapi进阶之四:异步编程(下篇)BeginInvoke( )/EndInvoke( )的使用
实现异步操作,除了用 async 和 await 这对组合之外,还可以通过委托对象的 BeginInvoke( ) 和 EndInvoke( ) 来完成 ,
为简单起见,我们直接使用系统为我们提供的内置委托 Func<T1,T2,...TResult>(或者不带返回值的Action<T1,T2...>委托也可以) ,代码如下:
(注:目前.net5 core 还不支持 BeginInvoke() 和 EndInvoke() 这种异步调用形式,需要用 .net5 framework环境 。)
class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Console.WriteLine("Main Thread ID = " + Thread.CurrentThread.ManagedThreadId); Demo51(); Console.ReadLine(); } private static int Demo51() { //定义一个Func<int,int>类型的委托 fx,功能:输入一个整数,+100后输出。 Func<int, int> fx = new Func<int, int>( x => { Console.WriteLine("Func<int, int>() Thread ID = " + Thread.CurrentThread.ManagedThreadId); return x + 100; } ); int ret = fx.Invoke(28); // Invoke() 是同步调用,即在当前主线程中调用 fx // BeginInvoke() 是异步调用,主线程会在线程池中取一个新线程来执行 fx,主线程会继续往下执行 IAsyncResult iar = fx.BeginInvoke(28, null, null); // do something1....这里可以加入业务代码 // EndInvoke() 用于获取 fx 的执行结果并释放线程使用的资源,在获取到结果之前主线程不会继续往下执行 int val = fx.EndInvoke(iar); // do something2....这里可以加入业务代码 return val; } }
运行程序其结果如下,可以看到调用 fx.Invoke( ) 和 fx.BeginInvoke( )的运行线程是不一样的。
在上面的例子中,当主线程执行到 "int val = fx.EndInvoke(iar);" 这条语句时如果 fx 还未执行完成,
主线程不会继续往下执行,会一直等待 fx 的执行结果,这种方式叫 "等待直到完成(wait-until-done)" 模式 ,
除了这种模式外,还有另外2种模式,分别是 "轮询(polling)"模式 和 "回调(callback)"模式,具体如下:
2. 轮询(polling)模式
private int Demo52() {
//定义一个Func<int,int>类型的委托 fx,功能:输入一个整数,+100后输出。 Func<int, int> fx = new Func<int, int>( x => { Console.WriteLine("Func<int, int>() Thread ID = " + Thread.CurrentThread.ManagedThreadId); return x + 100; } );
// BeginInvoke() 是异步调用,即在线程池中取一个新线程来执行 fx IAsyncResult iar = fx.BeginInvoke(28, null, null); // do something1....这里可以加入业务代码 // 判断 IAsyncResult.IsCompleted 属性来轮询 fx 是否执行完成 while (iar.IsCompleted == false) { // do something....这里可以加入业务代码 } // EndInvoke() 用于获取 fx 的执行结果并释放线程使用的资源 int val = fx.EndInvoke(iar); // do something2....这里可以加入业务代码 return val; }
轮询(polling)模式通过 IAsyncResult.IsCompleted 属性来判断 fx 是否执行完成 ,
我们可以在完成前和完成后做一些业务处理(测试略)。
3. 回调(callback)模式
private int callbackResult=0; private void CallbackFunc(IAsyncResult iar) { // state="test param",对应fx.BeginInvoke()的最后一个参数 string state = (string)iar.AsyncState; // 强制转型用于后面获取委托对象 fx AsyncResult ar = (AsyncResult)iar; Func<int, int> fx = (Func<int, int>)ar.AsyncDelegate; int callbackResult = fx.EndInvoke(iar); } private int Demo53() {
//定义一个Func<int,int>类型的委托 fx,功能:输入一个整数,+100后输出。 Func<int, int> fx = new Func<int, int>( x => { Console.WriteLine("Func<int, int>() Thread ID = " + Thread.CurrentThread.ManagedThreadId); return x + 100; } );
// BeginInvoke() 是异步调用,即在线程池中取一个新线程来执行 fx IAsyncResult iar = fx.BeginInvoke(28, CallbackFunc, "test param"); // do something....这里可以加入业务代码 // 在回调方法执行完成前,此值是0。 return callbackResult; }
回调(callback)模式中, fx.BeginInvoke( )第二个参数对应的回调函数 CallbackFunc 的签名必须符合
"void FuncName(IAsyncResult iar)" 的形式,最后一个参数是 object 类型,
可以传入任意对象,在回调函数中用 iar.AsyncState 取值后做强制转型就可以了(测试略)。
=================================分割线=================================
除了 async / await 和 delegate.BeginInvoke( ) / EndInvoke( ) 可以进行异步操作之外,
.net 还为我们提供了 System.Threading.Timer 、System.Threading.Tasks.Parallel 、
System.ComponentModel.BackgroundWorker 等类来做并行处理,
它们中部分更适用于GUI环境(如winform、WPF等),后续根据需要再做介绍。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人