簡體   English   中英

帶超時的異步 HTTPWebrequest

[英]Async HTTPWebrequest with Timeout

環境:Windows CE / .NET Compact FrameWork 3.5。

我需要一些指導

1) 為異步 Web 請求實現超時功能。 ThreadPool::RegisterWaitForSingleObject() 不適用於 .NetCf,我有點卡住了。

2)如何判斷網絡本身是否不可用? 谷歌搜索沒有幫助。

注意:ThreadPool::RegisterWaitForSingleObject 不適用於 .NET Compact FrameWork。

這是我的異步實現:

void StartRequest ()
{
    try
    {
        HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://192.78.221.11/SomeFunc/excpopulatedept");
        RqstState myRequestState = new RqstState();
        myRequestState.request = myHttpWebRequest;

        // Start the asynchronous request.
        IAsyncResult result =
                    (IAsyncResult)myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState);

        // Release the HttpWebResponse resource.
        myRequestState.response.Close();
    }
    catch (WebException ex)
    {
        ;
    }
    catch (Exception ex)
    {
        ;
    }
}

private void RespCallback(IAsyncResult asynchronousResult)
{
    try
    {
        //State of request is asynchronous.
        RqstState myRequestState = (RqstState)asynchronousResult.AsyncState;
        HttpWebRequest myHttpWebRequest = myRequestState.request;
        myRequestState.response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult);

        // Read the response into a Stream object.
        Stream responseStream = myRequestState.response.GetResponseStream();
        myRequestState.streamResponse = responseStream;

        // Begin the Reading of the contents of the HTML page and print it to the console.
        IAsyncResult asynchronousInputRead = responseStream.BeginRead(myRequestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallBack), myRequestState);
        return;
    }
    catch (WebException e)
    {
        Console.WriteLine("\nRespCallback Exception raised!");
        Console.WriteLine("\nMessage:{0}", e.Message);
        Console.WriteLine("\nStatus:{0}", e.Status);
    }
}

private void ReadCallBack(IAsyncResult asyncResult)
{
    try
    {
        RqstState myRequestState = (RqstState)asyncResult.AsyncState;
        Stream responseStream = myRequestState.streamResponse;
        int read = responseStream.EndRead(asyncResult);
        // Read the HTML page and then print it to the console.
        if (read > 0)
        {
            myRequestState.requestData.Append(Encoding.ASCII.GetString(myRequestState.BufferRead, 0, read));
            IAsyncResult asynchronousResult = responseStream.BeginRead(myRequestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallBack), myRequestState);
            return;
        }
        else
        {
            //Console.WriteLine("\nThe contents of the Html page are : ");
            if (myRequestState.requestData.Length > 1)
            {
                string stringContent;
                stringContent = myRequestState.requestData.ToString();
                responseStream.Close();
            }
            catch (WebException e)
            {
            }
        }
    }
}

感謝您的時間。

要繼續 Eric J 的評論,您在捕獲之前有myRequestState.response.Close() 這幾乎總是會拋出異常,因為要么response為空,要么response不會被打開。 這是因為您正在異步調用BeginGetResponse並且您給它的回調可能不會在調用下一行 (response.close) 時被調用。 你會想要解決這個問題,而不是僅僅隱藏異常,因為你不知道它們為什么會發生。

就超時而言,因為您正在處理的事情本身沒有可配置的超時,所以您必須設置一個計時器並在超時結束時簡單地關閉連接。 例如

HttpWebRequest myHttpWebRequest; // ADDED
Timer timer; // ADDED

private void StartRequest()
{
        myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://192.78.221.11/SomeFunc/excpopulatedept");
        RqstState myRequestState = new RqstState();
        myRequestState.request = myHttpWebRequest;

        timer = new Timer(delegate { if (!completed) myHttpWebRequest.Abort(); }, null, waitTime, Timeout.Infinite); // ADDED
        // Start the asynchronous request.
        IAsyncResult result =
                    (IAsyncResult)myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState);
}

//... 

private void ReadCallBack(IAsyncResult asyncResult)
{
    try
    {
        RqstState myRequestState = (RqstState)asyncResult.AsyncState;
        Stream responseStream = myRequestState.streamResponse;
        int read = responseStream.EndRead(asyncResult);
        // Read the HTML page and then print it to the console.
        if (read > 0)
        {
            myRequestState.requestData.Append(Encoding.ASCII.GetString(myRequestState.BufferRead, 0, read));
            IAsyncResult asynchronousResult = responseStream.BeginRead(myRequestState.BufferRead, 0, 1024, new AsyncCallback(ReadCallBack), myRequestState);
        }
        else
        {
            completed = true; // ADDED
            using(timer)  // ADDED
            {
                timer = null;
            }
            if (myRequestState.requestData.Length > 1)
            {
                string stringContent;
                stringContent = myRequestState.requestData.ToString();
                responseStream.Close();
            }
        }
    }
}

我只復制並粘貼了您的代碼,因此編譯的可能性與您最初提供的代碼一樣,但是應該有足夠的內容讓您朝着正確的方向前進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM