C#異步通信概念及應用淺析
C#異步通信概念及應用的認識首先讓我們來看看:在網(wǎng)絡編程中運用Socket,常常需要長期監(jiān)聽某個端口,以獲得Socket連接,進而執(zhí)行相關(guān)操作。
但此時,主線程就會被阻塞,無法做其他事情。為了解決這類問題,Socket類中提供了一些支持異步操作的方法,如表17-10所示。
下表為Socket類中支持異步操作的方法
方 法 |
說 明 |
BeginAccept() |
開始一個異步請求,以創(chuàng)建一個新的Socket對象來接受傳入的連接請求 |
EndAccept() |
結(jié)束一個異步請求,以創(chuàng)建一個新的Socket對象來接受傳入的連接請求 |
BeginConnect() |
開始一個對遠程主機的異步請求 |
EndConnect() |
結(jié)束一個對遠程主機的異步請求 |
BeginDisconnect() |
開始異步請求從遠程主機斷開連接 |
EndDisconnect() |
結(jié)束從遠程主機斷開連接的異步請求 |
BeginReceive() |
開始從連接的Socket中異步接收數(shù)據(jù) |
EndReceive() |
結(jié)束從連接的Socket中異步接收數(shù)據(jù) |
BeginReceiveFrom() |
開始從指定網(wǎng)絡設備中異步接收數(shù)據(jù) |
EndReceiveFrom() |
結(jié)束從指定網(wǎng)絡設備中異步接收數(shù)據(jù) |
BeginSend() |
開始將數(shù)據(jù)異步發(fā)送到連接的Socket中 |
EndSend() |
結(jié)束數(shù)據(jù)的異步發(fā)送 |
BeginSendFile() |
開始將文件異步發(fā)送到連接的Socket中 |
EndSendFile() |
結(jié)束文件的異步發(fā)送 |
BeginSendTo() |
向特定的遠程主機異步發(fā)送數(shù)據(jù) |
EndSendTo() |
結(jié)束對遠程主機數(shù)據(jù)的異步發(fā)送 |
從上表中可以看出,這些方法都是成對出現(xiàn)的。這些方法能避免網(wǎng)絡通信中的阻塞現(xiàn)象。這些方法的使用機制是在Begin開頭的方法中注冊一個回調(diào)函數(shù),當對應的事件發(fā)生時,調(diào)用該回調(diào)函數(shù),且在回調(diào)函數(shù)中調(diào)用對應的End開頭的方法。
下面以BeginAccept()和EndAccept()為例,說明異步方法的用法。BeginAccept()的聲明如下所示。
- public IAsyncResult BeginAccept(AsynCallback callback,
- object state);
其中,***個參數(shù)是異步委托AsynCallb了ack,state包含此請求的狀態(tài)信息的對象。
EndAccept()方法具有三種重載形式,如下所示。
- public Socket EndAccept(IAsyncResult asynresult);
- public Socket EndAccept(out byte[] buffer,
- IAsyncResult asynresult);
- public Socket EndAccept(out byte[] buffer,
- out int bytesTransferred, IAsyncResult asynresult,);
asynresult用于存儲此異步操作的狀態(tài)信息及任何用戶定義的數(shù)據(jù);buffer表示需要傳輸?shù)淖止?jié)數(shù)據(jù);
bytesTransferred表示已經(jīng)傳輸?shù)淖止?jié)數(shù)。這里的out參數(shù)與ref的用法類似,均表示傳遞引用。它們的區(qū)別是ref是傳遞參數(shù)的地址,out是返回值。
具體用法如下所示。
- private AsyncCallback callbackOnAccpt; //定制回調(diào)方法
- private Socket s;
- …… //C#異步通信
- s=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
- callbackAccpt = new AsyncCallback(this.OnAccept);//實例化回調(diào)方法
- s.BeginAccept(callbackOnAccpt, this.s); //開始異步請求
- ……
- private void OnAccept(IAsyncResult asynresult)
- {
- //C#異步通信
- ……
- s.EndAccept(asynresult); //結(jié)束異步請求
- ……
- }
BeginConnect()和EndConnect()用于對遠程主機的異步連接請求。BeginConnect()的聲明如下所示。
- public IAsyncResult BeginConnect(EndPoint remoteEP,
- AsyncCallback callback, object state);
- public IAsyncResult BeginConnect(IPAddress address,
- int port,AsyncCallback requestedcallback,object state);
- public IAsyncResult BeginConnect(IPAddress[] address,
- int port,AsyncCallback requestedcallback,object state);
- //C#異步通信
- public IAsyncResult BeginConnect(string host,int port,
- AsyncCallback requestedcallback,object state);
它的每個重載形式均含有AsyncCallback參數(shù),這是這類Begin開頭的方法的特點;remoteEP表示遠程主機的IP和端口。
EndConnect()的聲明如下所示。
public Socket EndConnect(IAsyncResult asynresult);
它的參數(shù)的意義和EndAccept()完全一致。
BeginSend()表示開始將數(shù)據(jù)異步發(fā)送到連接的Socket,它最常用的聲明如下所示。
- public IAsyncResult BeginSend(byte[] buffer,
- int offset,int size,SocketFlags socketFlags,
- AsyncCallback callback,object state);
Buffer表示要發(fā)送的數(shù)據(jù),offset表示buffer中發(fā)送數(shù)據(jù)的位置,size為發(fā)送字節(jié)數(shù)的大小,socketFlags指SocketFlags值的按位組合。
EndSend()的聲明如下所示。
- public Socket EndSend(IAsyncResult asynresult);
BeginReceive()表示開始從連接的Socket中異步接收數(shù)據(jù),它的常見聲明如下所示。
- public IAsyncResult BeginReceive(byte[] buffer,
- int offset,int size,SocketFlags socketFlags,
- AsyncCallback callback,object state);
它的參數(shù)和BeginSend()是完全一致的,這里不再贅述。
EndReceive()的聲明如下所示。
- public Socket EndReceive(IAsyncResult asynresult);
C#異步通信之Socket中異步通信的實現(xiàn)要遠比同步困難,這里不再舉例。簡單地說,在同步中,主線程如果調(diào)用一個方法,那么主線程必須等到方法線程執(zhí)行完才能繼續(xù)往下執(zhí)行。因此,主線程和方法線程的執(zhí)行是串行的。而在異步中,兩者能同時執(zhí)行,它們的執(zhí)行是并行的。
C#異步通信的相關(guān)內(nèi)容就向你介紹到這里,希望對你了解和學習C#異步通信有所幫助。
【編輯推薦】