简体   繁体   English

带超时的异步 HTTPWebrequest

[英]Async HTTPWebrequest with Timeout

Environemnt : Windows CE / .NET Compact FrameWork 3.5.环境:Windows CE / .NET Compact FrameWork 3.5。

I need some guidance in我需要一些指导

1) Implementing a Timeout functionality for an Asynchronous Web request. 1) 为异步 Web 请求实现超时功能。 ThreadPool::RegisterWaitForSingleObject() is not available for .NetCf and I'm bit stuck. ThreadPool::RegisterWaitForSingleObject() 不适用于 .NetCf,我有点卡住了。

2) How to determine if network itself is not avaialable? 2)如何判断网络本身是否不可用? Googling didn't help.谷歌搜索没有帮助。

Note : ThreadPool::RegisterWaitForSingleObject is not available for .NET Compact FrameWork.注意:ThreadPool::RegisterWaitForSingleObject 不适用于 .NET Compact FrameWork。

Here is my Async implementation:这是我的异步实现:

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)
            {
            }
        }
    }
}

Thank you for your time.感谢您的时间。

To continue what Eric J commented on, you have myRequestState.response.Close() just before your catches.要继续 Eric J 的评论,您在捕获之前有myRequestState.response.Close() That's almost always going to throw an exception because either response will be null, or response won't be opened.这几乎总是会抛出异常,因为要么response为空,要么response不会被打开。 This is because you are asynchronously calling BeginGetResponse and the callback you give it will likely not be called by the time the next line (response.close) is called.这是因为您正在异步调用BeginGetResponse并且您给它的回调可能不会在调用下一行 (response.close) 时被调用。 You'll want to fix that instead of just hiding the exceptions because you don't know why they occur.你会想要解决这个问题,而不是仅仅隐藏异常,因为你不知道它们为什么会发生。

In terms of a timeout, because you're dealing with something that doesn't inherently have a configurable timeout, you'll have to set a timer and simply close the connection at the end of the time-out.就超时而言,因为您正在处理的事情本身没有可配置的超时,所以您必须设置一个计时器并在超时结束时简单地关闭连接。 eg例如

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

I only copy and pasted your code, so it's as likely to compile as what you originally provided, but there should be enough there you get in going in the right direction.我只复制并粘贴了您的代码,因此编译的可能性与您最初提供的代码一样,但是应该有足够的内容让您朝着正确的方向前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM