|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
c语言的编译器,几乎是所有新平台都有的。因此从这点上看,c语言的程序,比其他任何语言更加容易跨平台。说到异步伐用,在脑海中起首想到就是BeginInvoke(),在一些经常使用工具中我们也会经常见到Invoke()和BeginInvoke(),要想让本人的组件能够被客户端挪用大概是异步伐用,如许的计划是公道的,这也是组件异步机制傍边的一条(说句题外话--实在年夜多半常识都埋没在我们平常常常见到的工具大概是代码里,只不外是没有往仔细的发明)在.NET中起首就会想到利用托付来举行异步伐用,关于托付的界说在托付与事务一文中已也许的说过了,文中只是对托付举行了也许的解说,并没有对托付的利用来讲明大概是例举一些示例。在本篇中将会对托付举行一个基本的揭底,次要偏向是异步伐用。
一托付的老调重弹- publicclassOperation{publicintAddition(intnum1,intnum2){returnnum1+num2;}publicintSubtraction(intnum1,intnum2){returnnum1-num2;}}
复制代码 没有需要间接利用Operation工具来举行加减运算,可使用托付:- publicdelegateintOperationDelegate(intnum1,intnum2);Operationoperation=newOperation();OperationDelegateAdditiondelegate=operation.Addition;intresult;result=Additiondelegate.Invoke(3,4);Debug.Assert(result==7);
复制代码 在利用托付举行挪用的时分,以后线程是被堵塞的,只要当托付实行终了了,才会把把持权交回到以后线程。
不外呢,托付能够用于举行异步伐用方针办法的,托付只是一种特定的范例,编译器会把我们界说的形形色色的托付编译成
对应的类,比如OperationDelegate托付一样,实则是被编译成如许的- publicsealedclassOperationDelegate:MulticastDelegate{publicOperationDelegate(Objecttarget,intmethodPtr){}publicvirtualInvoke(intnum1,intnum2){……}publicvirtualIAsyncResultBeginInvoke(intnum1,intnum2,AsyncCallbackcallback,objectasyncState){……}publicvirtualintEndInvoke(IAsyncResultresult){……}}
复制代码 这里只是回忆一下托付的界说。
二异步伐用编程模子
在上图我们所见的有这几个模块,.NET线程池、异步伐用哀求行列和一个使用程序的主线程。
倘使如今从义务1入手下手实行就任务2、义务3,到了义务3的时分,义务3哀求.NET实行异步操纵,如
这个时分【义务3】已被送进到了【异步哀求行列】中,而且主线程是堵塞形态的,再看的实行历程:
线程池会实时的发明【异步哀求行列】中的义务,而且依据义务的信息,线程池会分派一个线程就任务地点的主线程中实行所哀求的义务。在异步义务实行时,这个时分主线程才会从堵塞中打消,进进实行形态,上图中,就是入手下手实行义务4。
这里要说的就是,异步伐用看起来是并行实行的,实践刚入手下手的时分仍是按次的,不外这时候间在实践情形中是疏忽不计的,能够以为就是并行实行的吧。
三BeginInvoke()、EndInvoke()
3.1BeginInvoke()
BeginInvoke()函数界说以下:- 1publicvirtualIAsyncResultBeginInvoke(intnum1,intnum2,AsyncCallbackcallback,objectasyncState)2{3……4}
复制代码 承受OperationDelegate托付界说的原始署名的输出参数,另有两个分外参数,AsyncCallback是体系界说的托付,用于异步伐用完成时回调所用,这里不做解说,前面会有讲到,另有一个是参数是一个形态工具,也能够以为是容器工具,也会在前面的章节中讲到。- 1Operationoperation=newOperation();2OperationDelegateAdditiondelegate=operation.Addition;3Additiondelegate.BeginInvoke(3,4,null,null);
复制代码 3.2IAsyncResult接口
正如下面所看到的,BeginInvoke函数前往一个IAsyncResult范例的值,那就来看一下IAsyncResult的界说:- publicinterfaceIAsyncResult{objectAsyncState{get;}WaitHandleAsyncWaitHandle{get;}boolCompletedSynchronously{get;}boolIsCompleted{get;}}
复制代码 关于IAsyncResult的具体用法稍后会有解说
看到第一节的Invoke函数实行后,能够间接猎取到前往值,怎样这个BeginInvoke函数实行了前往
IAsyncResult范例,前往值在哪呢?能够经由过程从BeginInvoke函数取得的IAsyncResult交给EndInvoke函数来猎取前往值。
1Operationoperation=newOperation();
2OperationDelegateAdditiondelegate=operation.Addition;
3
4IAsyncResultasyncResult=Additiondelegate.BeginInvoke(3,4,null,null);
5intresult=Additiondelegate.EndInvoke(asyncResult);
6Debug.Assert(result==7);
这里要说几点
第一.挪用EndInvoke函数的时分,以后线程是被堵塞的,它在守候BeginInvoke函数实行终了。
第二.固然托付能够办理多个方针办法,可是在异步伐用中,所实行异步伐用的托付,外部的办理列表只能有一个方针办法,否则会报有非常。
第三.EndInvoke()在每次异步伐用操纵时只能挪用一次。
第四.BeginInvoke()前往的IAsyncResult范例的实例,只能传进它所挪用BeginInvoke()托付的EndInvoke()中,否则也会报有非常。
3.3AsyncResult
倘使一个客户端在一个代码段大概是函数中利用BeginInvoke(),而在另外一段大概是其他的函数中挪用EndInvoke(),如许客户端是不是就要保留IAsyncResult工具,又大概一个客户端倡议异步伐用,而且由另外一个客户端来挪用EndInvoke(),这不单单要保留IAsyncResult工具,还必要保留该托付工具,并且你还得传送已往。还好.NET是那末的机灵,有System.Runtime.Remoting.Messaging.AsyncResult范例的存在。
publicclassAsyncResult:IAsyncResult,IMessageSink
{
#regionIAsyncResult成员
publicobjectAsyncState
{
get{thrownewNotImplementedException();}
}
publicSystem.Threading.WaitHandleAsyncWaitHandle
{
get{thrownewNotImplementedException();}
}
publicboolCompletedSynchronously
{
get{thrownewNotImplementedException();}
}
publicboolIsCompleted
{
get{thrownewNotImplementedException();}
}
#endregion
publicboolEndInvokeCalled{get;set;}
publicvirtualobjectAsyncDelegate{get;}
//IMessageSink成员
}
看着下面有个AsyncDelegate的属性,会不会以为很大度,不错,它就是原始倡议托付的援用,看下怎样利用AsyncDelegate来利用EndInvoke():
publicclassOperationTest
{
publicvoidTest()
{
Operationoperation=newOperation();
OperationDelegateAdditiondelegate=operation.Addition;
intResult;
Result=GetResult(Additiondelegate.BeginInvoke(3,4,null,null));
}
privateintGetResult(IAsyncResultasyncresult)
{
AsyncResultasyncResult=(AsyncResult)asyncresult;
OperationDelegateoperationdelegate=asyncResult.AsyncDelegateas
OperationDelegate;
if(operationdelegate!=null)
{
Debug.Assert(asyncResult.EndInvokeCalled==false);//EndInvoke()是不是被挪用过
returnoperationdelegate.EndInvoke(asyncResult);
}
return-1;
}
}
3.4轮循或守候
看到这里,擅长思索的伴侣会发明,还存在着一个很年夜的成绩,就是倡议异步伐用的客户端,怎样晓得本人的异步函数是不是实行终了了?大概是想守候一会,做一些其他的处置,然后再持续守候,该怎样来完成呢?
从BeginInvoke()前往的IAsyncResult接口有个AsyncWaitHandle属性,它是干嘛的呢?就把它了解为动静吸收器吧。
Operationoperation=newOperation();
OperationDelegateAdditiondelegate=operation.Addition;
IAsyncResultasyncResult=Additiondelegate.BeginInvoke(2,3,null,null);
asyncResult.AsyncWaitHandle.WaitOne();//假如义务完成则不会堵塞不然堵塞以后线程
intResult;
Result=Additiondelegate.EndInvoke(asyncResult);
Debug.Assert(Result==5);
代码和3.2的几近不异,区分就是这段代码包管了EndInvoke()的挪用者不会被堵塞。
看一上等待一下,假如没完成处置其他义务,返来再守候是怎样完成的。
Operationoperation=newOperation();
OperationDelegateAdditiondelegate=operation.Addition;
IAsyncResultasyncResult=Additiondelegate.BeginInvoke(2,3,null,null);
while(asyncResult.IsCompleted==false)//判别异步义务是不是完成
{
asyncResult.AsyncWaitHandle.WaitOne(10,false);//假如义务完成则不会堵塞不然堵塞以后线程10毫秒
//这里做一些其他操纵
}
intResult;
Result=Additiondelegate.EndInvoke(asyncResult);
Debug.Assert(Result==5);
3.5利用回调函数
如今我们要来讲说BeginInvoke()的第三个参数了,publicdelegatevoidAsyncCallback(IAsyncResultar);
第三个参数就是体系供应的一个托付范例,托付署名也都看到了。利用回调函数的优点就是不必要去向理守候操纵了,由于在异步义务完成的时分,会挪用你传给BeginInvoke()里AsyncCallback托付所联系关系的方针办法。
publicclassOperationTest
{
publicvoidTest()
{
Operationoperation=newOperation();
OperationDelegateAdditiondelegate=operation.Addition;
Additiondelegate.BeginInvoke(2,3,newAsyncCallback(OnCallBack),null);
}
privatevoidOnCallBack(IAsyncResultasyncresult)
{
AsyncResultasyncResult=(AsyncResult)asyncresult;
OperationDelegateoperationdelegate=asyncResult.AsyncDelegateas
OperationDelegate;
if(operationdelegate!=null)
{
Debug.Assert(asyncResult.EndInvokeCalled==false);
intresult=operationdelegate.EndInvoke(asyncResult);
Console.WriteLine("Operationreturned"+result.ToString());
}
}
}
这里必要说的是在异步义务完成时,实行的回调函数仍然是在子线程傍边,并非在主线程中实行回调函数的。
题外话:最多见的就是在Winform开辟中,Form中倡议异步伐用,然后回调函数操纵Form中的控件大概是
值的时分就会报错,就是这个缘故原由,由于它们不在一个线程也不在一个高低文中,基于.NET平安战略这类操纵是不同意的。
如果英语好,口才好,加上女孩子的优势说不定有机会进去做做别的工具) |
|