| 實現異步請求system.net 類使用 .net 框架的標準異步編程模型對 internet 資源進行異步訪問。webrequest 類的 begingetresponse 和 endgetresponse 方法分別啟動和完成對 internet 資源的異步請求。 注意 在異步回調方法中使用同步調用可能會導致嚴重的性能降低。通過 webrequest 及其子代實現的 internet 請求必須使用 stream.beginread 讀取由 webresponse.getresponsestream 方法返回的流。 下面的 c# 示例程序說明如何通過 webrequest 類使用異步調用。該示例是一個控制臺程序,它從命令行獲得 uri,請求此 uri 處的資源,然后在從 internet 接收數據的過程中在控制臺上打印數據。 該程序定義了兩個供自己使用的類:一個是 requeststate 類,它在異步調用間傳遞數據;另一個是 clientgetasync 類,它實現對 internet 資源的異步請求。 requeststate 類在服務于請求的異步方法調用間保留請求的狀態。在 requeststate 類中,有包含當前資源請求和收到的響應流的 webrequest 和 stream 實例、包含當前從 internet 資源接收到的數據的緩沖區和包含整個響應的 stringbuilder 實例。當 asynccallback 方法向 webrequest.begingetresponse 注冊時,requeststate 實例 (ar) 作為 state 參數傳遞。 clientgetasync 類實現對 internet 資源的異步請求,并將結果響應寫到控制臺。此類包含以下列表中描述的方法和屬性。 
 注意 關閉所有網絡流至關重要。如果沒有將所有的請求和響應流都關閉,應用程序將用完服務器連接,而無法處理其他請求。 [c#] using system; using system.net; using system.threading; using system.text; using system.io; // the requeststate class passes data across async calls. public class requeststate { const int buffersize = 1024; public stringbuilder requestdata; public byte[] bufferread; public webrequest request; public stream responsestream; // create decoder for appropriate enconding type. public decoder streamdecode = encoding.utf8.getdecoder(); public requeststate() { bufferread = new byte[buffersize]; requestdata = new stringbuilder(string.empty); request = null; responsestream = null; } } // clientgetasync issues the async request. class clientgetasync { public static manualresetevent alldone = new manualresetevent(false); const int buffer_size = 1024; public static void main(string[] args) { if (args.length < 1) { showusage(); return; } // get the uri from the command line. uri httpsite = new uri(args[0]); // create the request object. webrequest wreq = webrequest.create(httpsite); // create the state object. requeststate rs = new requeststate(); // put the request into the state object so it can be passed around. rs.request = wreq; // issue the async request. iasyncresult r = (iasyncresult) wreq.begingetresponse( new asynccallback(respcallback), rs); // wait until the manualresetevent is set so that the application // does not exit until after the callback is called. alldone.waitone(); console.writeline(rs.requestdata.tostring()); } public static void showusage() { console.writeline("attempts to get a url"); console.writeline("/r/nusage:"); console.writeline(" clientgetasync url"); console.writeline(" example:"); console.writeline(" clientgetasync http://www.contoso.com/"); } private static void respcallback(iasyncresult ar) { // get the requeststate object from the async result. requeststate rs = (requeststate) ar.asyncstate; // get the webrequest from requeststate. webrequest req = rs.request; // call endgetresponse, which produces the webresponse object // that came from the request issued above. webresponse resp = req.endgetresponse(ar); // start reading data from the response stream. stream responsestream = resp.getresponsestream(); // store the response stream in requeststate to read // the stream asynchronously. rs.responsestream = responsestream; // pass rs.bufferread to beginread. read data into rs.bufferread iasyncresult iarread = responsestream.beginread(rs.bufferread, 0, buffer_size, new asynccallback(readcallback), rs); } private static void readcallback(iasyncresult asyncresult) { // get the requeststate object from asyncresult. requeststate rs = (requeststate)asyncresult.asyncstate; // retrieve the responsestream that was set in respcallback. stream responsestream = rs.responsestream; // read rs.bufferread to verify that it contains data. int read = responsestream.endread( asyncresult ); if (read > 0) { // prepare a char array buffer for converting to unicode. char[] charbuffer = new char[buffer_size]; // convert byte stream to char array and then to string. // len contains the number of characters converted to unicode. int len = rs.streamdecode.getchars(rs.bufferread, 0, buffer_size, charbuffer, 0); string str = new string(charbuffer, 0, len); // append the recently read data to the requestdata stringbuilder // object contained in requeststate. rs.requestdata.append( encoding.ascii.getstring(rs.bufferread, 0, read)); // continue reading data until // responsestream.endread returns –1. iasyncresult ar = responsestream.beginread( rs.bufferread, 0, buffer_size, new asynccallback(readcallback), rs); } else { if(rs.requestdata.length>0) { // display data to the console. string strcontent; strcontent = rs.requestdata.tostring(); } // close down the response stream. responsestream.close(); // set the manualresetevent so the main thread can exit. alldone.set(); } return; } } 使用應用程序協議.net 框架支持 internet 上通用的應用程序協議。本節內容包括關于在 .net 框架中使用 http、tcp 和 udp 支持的信息,和關于使用 windows 套接字接口實現自定義協議的信息。 http.net 框架使用 httpwebrequest 和 httpwebresponse 類來提供對 http 協議的全面支持,而 http 協議構成了大部分的 internet 通信量。每當靜態方法 webrequest.create 遇到以“http”或“https”開頭的 uri 時,在默認情況下將返回這些從 webrequest 和 webresponse 派生的類。多數情況下,webrequest 和 webresponse 類提供生成請求所需的一切,但如果需要訪問作為屬性公開的 http 特定功能,則可以將這些類的類型轉換為 httpwebrequest 或 httpwebresponse。 httpwebrequest 和 httpwebresponse 封裝“標準 http 請求和響應”事務,并提供對通用 http 標頭的訪問。這些類還支持大部分的 http 1.1 功能,其中包括管線、塊區、身份驗證、預身份驗證、加密、代理支持、服務器證書驗證以及連接管理。自定義標頭和不是通過屬性提供的標頭可存儲在 headers 屬性中并可通過此屬性訪問。 以下示例顯示如何訪問 http 特定的屬性,在本例中為關閉 http keep-alive 行為并從 web 服務器獲取協議版本號。 [c#] httpwebrequest httpwreq = (httpwebrequest)webrequest.create("http://www.contoso.com");// turn off connection keep-alives. httpwreq.keepalive = false; httpwebresponse httpwresp = (httpwebresponse)httpwreq.getresponse(); // get the http protocol version number returned by the server. string ver = httpwresp.protocolversion.tostring(); httpwresp.close(); httpwebrequest 是 webrequest 使用的默認類,不需要注冊它就可以將 uri 傳遞給 webrequest.create 方法。 可以通過將 allowautoredirect 屬性設置為 true(默認值)使應用程序自動遵循 http 重定向。應用程序將重定向請求,而 httpwebresponse 的 responseuri 屬性則將包含響應請求的實際 web 資源。如果將 allowautoredirect 設置為 false,則應用程序必須能夠將重定向作為 http 協議錯誤處理。 應用程序通過捕捉 status 設置為 webexceptionstatus.protocolerror 的 webexception 來接收 http 協議錯誤。response 屬性包含由服務器發送的webresponse,并指示遇到的實 | 
新聞熱點
疑難解答
圖片精選