C# dll 事件執行 js 回調函數


前言:

  由於js 遠程請求  XMLHttpRequest() 不支持多線程,所以用C# 寫了個dll 多線程遠程抓住供js調用。

最初代碼為:

  C#代碼

/// <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能不能注冊一個回調函數。 開始一通嘗試,最終找到相關答案:

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);

當運行后就會 彈出 百度源代碼

這就實現了異步回調

 

 

 http://files.cnblogs.com/echosong/http.rar 完整demo下載(先點reg.bat先注冊dll)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM