-
C#教程之C#异步调用的好处和方法分享
异步方法很好的解决了这些问题,异步执行某个方法,程序立即开辟一个新线程去运行你的方法,主线程包括界面就不会死掉了。异步如何开始,好理解,现在我们讨论的是如何结束这个异步出来的新线程。
首先,异步出来的新线程,必须回收,不回收是浪费资源的可耻行为,.NET也是不允许的,所以你别想钻空子,俗话说,请神容易送神难,就是这个道理。下面你可以很容易想到,回收分为2种情况:主动回收和被动回收(当然,这是我自己的理解,微软可不是这么说的),主动回收就是,你去监视那个线程,并且等待,当异步方法完成了,就把异步线程回收,焦点回归主线程,实际上就是上篇文章《C#异步初步》的那种情况,BeginInvoke之后又EndInvoke,如果在EndInvoke的时候,该异步线程没有完成操作,那么整个程序,包括主线程,又在阻塞了,又会出现界面“死”的情况。要想解决这个问题,就使用“被动回收”方式,其中一个重要的办法就是“异步回调”。 核心有二: A、 用回调函数(本例中为CallBackMethod),异步结束后,自动调用此回调函数。 B、 而不在主线程中手工等待异步结束,如上两例中在主线程中调用EndInvoke。此种方法,是在回调函数中调用EndInvoke的。 异步回调的大概流程是这样的:首先启动异步,启动参数加上异步结束时执行的方法,然后这个异步线程就不用管了,最后当这个异步线程自己完成工作了,就自动执行启动参数里的那个方法,这样确实很省心,可是代码写起来,就很复杂了。 下面是搜藏的代码:
//首先准备好,要进行异步的方法(能异步的,最好不多线程)
privatestringMethodName(intNum,outintNum2)
{
Num2=Num;
return"HelloWorld";
}
//程序终点
//异步完成时,执行的方法(回调方法),此方法只能有IAsyncResult一个参数,但是该参数几乎万能,可以传递object
privatevoidCallBackMethod(IAsyncResultar)
{
//从异步状态ar.AsyncState中,获取委托对象
DelegateNamedn=(DelegateName)ar.AsyncState;
//输出参数
inti;
//一定要EndInvoke,否则你的下场很惨
stringr=dn.EndInvoke(outi,ar);
MessageBox.Show("异步完成喽!i的值是"i.ToString()",r的值是"r);
}
//定义与方法同签名的委托
privatedelegatestringDelegateName(intNum,outintNum2);
//程序入口
privatevoidRun()
{
//实例化委托并初赋值
DelegateNamedn=newDelegateName(MethodName);
//输出参数
inti;
//实例化回调方法
//把AsyncCallback看成Delegate你就懂了,实际上AsyncCallback是一种特殊的Delegate,就像Event似的
AsyncCallbackacb=newAsyncCallback(CallBackMethod);
//异步开始
//如果参数acb换成null则表示没有回调方法
//最后一个参数dn的地方,可以换成任意对象,该对象可以被回调方法从参数中获取出来,写成null也可以。参数dn相当于该线程的ID,如果有多个异步线程,可以都是null,但是绝对不能一样,不能是同一个object,否则异常
IAsyncResultiar=dn.BeginInvoke(1,outi,acb,dn);
//去做别的事
//…………
}
//最后的结果应该是:i=1,r="HelloWorld"
//另外,如果可以,定义委托的时候可以选择不用过多的修饰:
///<summary>
///定义委托
///</summary>
///<returns></returns>
publicdelegateboolAsyncdelegate();
///<summary>
///Callbackmethodmusthavethesamesignatureasthe
///AsyncCallbackdelegate
///</summary>
///<paramname="ar"></param>
privatevoidCallbackMethod(IAsyncResultar)
{
//Retrievethedelegate.
Asyncdelegatedlgt=(Asyncdelegate)ar.AsyncState;
//CallEndInvoketoretrievetheresults.
dlgt.EndInvoke(ar);
}
//其他方法中调用:
//异步执行
//指定委托方法
Asyncdelegateisgt=newAsyncdelegate(icpInfo.Insert);
IAsyncResultar=isgt.BeginInvoke(newAsyncCallback(CallbackMethod),isgt);
首先,异步出来的新线程,必须回收,不回收是浪费资源的可耻行为,.NET也是不允许的,所以你别想钻空子,俗话说,请神容易送神难,就是这个道理。下面你可以很容易想到,回收分为2种情况:主动回收和被动回收(当然,这是我自己的理解,微软可不是这么说的),主动回收就是,你去监视那个线程,并且等待,当异步方法完成了,就把异步线程回收,焦点回归主线程,实际上就是上篇文章《C#异步初步》的那种情况,BeginInvoke之后又EndInvoke,如果在EndInvoke的时候,该异步线程没有完成操作,那么整个程序,包括主线程,又在阻塞了,又会出现界面“死”的情况。要想解决这个问题,就使用“被动回收”方式,其中一个重要的办法就是“异步回调”。 核心有二: A、 用回调函数(本例中为CallBackMethod),异步结束后,自动调用此回调函数。 B、 而不在主线程中手工等待异步结束,如上两例中在主线程中调用EndInvoke。此种方法,是在回调函数中调用EndInvoke的。 异步回调的大概流程是这样的:首先启动异步,启动参数加上异步结束时执行的方法,然后这个异步线程就不用管了,最后当这个异步线程自己完成工作了,就自动执行启动参数里的那个方法,这样确实很省心,可是代码写起来,就很复杂了。 下面是搜藏的代码:
复制代码 代码如下:
//首先准备好,要进行异步的方法(能异步的,最好不多线程)
privatestringMethodName(intNum,outintNum2)
{
Num2=Num;
return"HelloWorld";
}
//程序终点
//异步完成时,执行的方法(回调方法),此方法只能有IAsyncResult一个参数,但是该参数几乎万能,可以传递object
privatevoidCallBackMethod(IAsyncResultar)
{
//从异步状态ar.AsyncState中,获取委托对象
DelegateNamedn=(DelegateName)ar.AsyncState;
//输出参数
inti;
//一定要EndInvoke,否则你的下场很惨
stringr=dn.EndInvoke(outi,ar);
MessageBox.Show("异步完成喽!i的值是"i.ToString()",r的值是"r);
}
//定义与方法同签名的委托
privatedelegatestringDelegateName(intNum,outintNum2);
//程序入口
privatevoidRun()
{
//实例化委托并初赋值
DelegateNamedn=newDelegateName(MethodName);
//输出参数
inti;
//实例化回调方法
//把AsyncCallback看成Delegate你就懂了,实际上AsyncCallback是一种特殊的Delegate,就像Event似的
AsyncCallbackacb=newAsyncCallback(CallBackMethod);
//异步开始
//如果参数acb换成null则表示没有回调方法
//最后一个参数dn的地方,可以换成任意对象,该对象可以被回调方法从参数中获取出来,写成null也可以。参数dn相当于该线程的ID,如果有多个异步线程,可以都是null,但是绝对不能一样,不能是同一个object,否则异常
IAsyncResultiar=dn.BeginInvoke(1,outi,acb,dn);
//去做别的事
//…………
}
//最后的结果应该是:i=1,r="HelloWorld"
//另外,如果可以,定义委托的时候可以选择不用过多的修饰:
///<summary>
///定义委托
///</summary>
///<returns></returns>
publicdelegateboolAsyncdelegate();
///<summary>
///Callbackmethodmusthavethesamesignatureasthe
///AsyncCallbackdelegate
///</summary>
///<paramname="ar"></param>
privatevoidCallbackMethod(IAsyncResultar)
{
//Retrievethedelegate.
Asyncdelegatedlgt=(Asyncdelegate)ar.AsyncState;
//CallEndInvoketoretrievetheresults.
dlgt.EndInvoke(ar);
}
//其他方法中调用:
//异步执行
//指定委托方法
Asyncdelegateisgt=newAsyncdelegate(icpInfo.Insert);
IAsyncResultar=isgt.BeginInvoke(newAsyncCallback(CallbackMethod),isgt);
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式