前言:javascript
因爲js 遠程請求 XMLHttpRequest() 不支持多線程,因此用C# 寫了個dll 多線程遠程抓住供js調用。java
最初代碼爲:編程
C#代碼windows
/// <summary> /// 異步請求入口 /// </summary> /// <param name="url">傳入http地址 注意加http</param> /// <param name="timeoutStr">超時時間</param> public void AsyncGet(string url, int timeoutStr) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url)); request.Timeout = timeoutStr; request.BeginGetResponse(new AsyncCallback(ReadCallBack), request); } catch (Exception) { } } /// <summary> /// 執行回調時候異步最終拿到值 /// 正常獲取反饋值,異常時候值爲 timeout /// </summary> public string returnContent { get; set; } /// <summary> /// 執行異步回調請求 /// </summary> /// <param name="asynchronousResult"></param> private void ReadCallBack(IAsyncResult asynchronousResult) { try { HttpWebRequest reqeust = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse response = (HttpWebResponse)reqeust.EndGetResponse(asynchronousResult); StreamReader readContent = new StreamReader(response.GetResponseStream()); returnContent = readContent.ReadToEnd().ToString(); } catch (Exception) { returnContent = "timeout"; } }
js 代碼:
多線程
var Gtime = 5; function getUrl (turl) { if (Gtime==5) { comActiveX.AsyncGet(turl,Gtime); } if (Gtime>0 && comActiveX.returnContent==undefined) { setTimeout("getUrl('"+turl+"')",1000); alert(comActiveX.returnContent); Gtime -- ; }else{ document.write( comActiveX.returnContent); } }
這裏存在問題,js必須一直去詢問dll 是否獲取到數據,直到獲取到數據才作下面處理,雖然其中能夠作其餘事情,可是這跟同步等待沒有多大區別。異步
windows 經典編程 有句話叫「don't call me , I will call you!」 ,這就是事件的引入,那麼這裏能夠不能夠優化爲,當有數據拿到之後自動通知js,js能不能註冊一個回調函數。 開始一通嘗試,最終找到相關答案:async
C# 加入如下代碼:函數
public delegate void EventHandler(string data); [Guid("9771B223-6188-4849-B292-C7D9D8173E49")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ControlEvents { [DispId(0x60020000)] void eventsGet(string data); } /// <summary> /// 採集類 /// </summary> [ClassInterface(ClassInterfaceType.AutoDual), ComSourceInterfaces(typeof(ControlEvents))] public class CollectGood : UserControl { public event EventHandler eventsGet; private delegate void UpEventDelegate(string msg); public void Reback(string msg) { UpEventDelegate up = new UpEventDelegate(UpEvent); this.BeginInvoke(up, msg); } private void UpEvent(string msg) { if (eventsGet != null) { eventsGet(msg); } } #region httpWebRequest 異步請求Get方法 /// <summary> /// 異步請求入口 /// </summary> /// <param name="url">傳入http地址 注意加http</param> /// <param name="timeoutStr">超時時間</param> public void AsyncGet(string url, int timeoutStr) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url)); request.Timeout = timeoutStr; request.BeginGetResponse(new AsyncCallback(ReadCallBack), request); } catch (Exception) { } } /// <summary> /// 執行回調時候異步最終拿到值 /// 正常獲取反饋值,異常時候值爲 timeout /// </summary> public string returnContent { get; set; } /// <summary> /// 執行異步回調請求 /// </summary> /// <param name="asynchronousResult"></param> private void ReadCallBack(IAsyncResult asynchronousResult) { try { HttpWebRequest reqeust = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse response = (HttpWebResponse)reqeust.EndGetResponse(asynchronousResult); StreamReader readContent = new StreamReader(response.GetResponseStream()); returnContent = readContent.ReadToEnd().ToString(); Reback(returnContent); } catch (Exception) { returnContent = "timeout"; } } #endregion
js部分:優化
<OBJECT id="comActiveX" width="" height="" classid="CLSID:7b8bfbe3-7f62-47e0-919c-6aa2315e6db9"> </OBJECT> <SCRIPT type="text/javascript"> //var comActiveX; try { //comActiveX = new ActiveXObject("HttpAsy.CollectGood"); } catch (e) { // alert("沒有註冊好"); } comActiveX.attachEvent("eventsGet",function(msg){alert(msg)}) comActiveX.AsyncGet("http:/www.baidu.com",5);
當運行後就會 彈出 百度源代碼ui
這就實現了異步回調
http://files.cnblogs.com/echosong/http.rar 完整demo下載(先點reg.bat先註冊dll)