.NET HTTP请求超时不是"正在中止"在连续流媒体网站上

时间:2015-01-02 17:08:29

标签: c# httprequest

范围

我为Http Web Request类开发了一个Wrapper,以更简单的方式执行Get和Posts。这个库已经使用了两年多没有任何问题,但今天,我们遇到了一个奇怪的问题。

one website(加载需要一段时间),显然,它会将字符流保存到HTML前端,因此我们的库" Get"请求陷入循环。

不同的超时属性

查看Http Web Request参考,我们发现有两个不同的timeout属性。我们正在使用它们,但它们似乎都没有正常中止。

  • Read Write Timeout - 获取或设置写入或读取流时的超时(以毫秒为单位)。
  • Timeout - 获取或设置GetResponse和GetRequestStream方法的超时值(以毫秒为单位)。

一次性排除所有

有没有办法设置"操作超时"这将在一些预先配置的时间后强制流/连接处理?

部分代码示例

public class Program
{
public static void Main()
{
    string url = "http://anus.io";

    Console.WriteLine("Initializing Request State Object");

    RequestState myRequestState = new RequestState();

    // Creating Http Request
    myRequestState.request  =  (HttpWebRequest)WebRequest.Create(url);
    myRequestState.request.Method           = "GET";
    myRequestState.request.ReadWriteTimeout = 4000;
    myRequestState.request.Timeout          = 4000;

    Console.WriteLine("Begining Async Request");


    IAsyncResult ar = myRequestState.request.BeginGetResponse(new AsyncCallback(ResponseCallback), myRequestState);

    Console.WriteLine("Waiting for Results");
    ar.AsyncWaitHandle.WaitOne();

    myRequestState.response = (HttpWebResponse)myRequestState.request.EndGetResponse(ar);
    Console.WriteLine("Response status code = {0}", myRequestState.response.StatusCode);

}

public static void ResponseCallback (IAsyncResult asyncResult)
{
    Console.WriteLine("Completed");
}
}

This Code seem to work fine,但我如何将响应作为字符串读取,因为它经常被传输(如浏览器所示)?

问题

处理此类网站的正确方法是什么? (通过句柄我的意思是能够识别并跳过服务器只是赢得停止传输的情况?)

2 个答案:

答案 0 :(得分:1)

试试这个:

public static void Main()
{

    string url = "http://anus.io";

    ***int DefaultTimeOut = 15000;*** //timeout after 15 sec

    Console.WriteLine("Initializing Request State Object");

    RequestState myRequestState = new RequestState();

    // Creating Http Request
    myRequestState.request  =  (HttpWebRequest)WebRequest.Create(url);
    myRequestState.request.Method           = "GET";
    myRequestState.request.ReadWriteTimeout = 4000;
    myRequestState.request.Timeout          = 4000;

    Console.WriteLine("Begining Async Request");


    IAsyncResult ar = myRequestState.request.BeginGetResponse(new AsyncCallback(ResponseCallback), myRequestState);

    ***ThreadPool.RegisterWaitForSingleObject(ar.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), myRequestState.request, DefaultTimeOut, true);***

    Console.WriteLine("Waiting for Results");
    ar.AsyncWaitHandle.WaitOne();

    try{

    myRequestState.response = (HttpWebResponse)myRequestState.request.EndGetResponse(ar);
    Console.WriteLine("Response status code = {0}", myRequestState.response.StatusCode);
    }catch(Exception){
       Console.WriteLine("Request Aborted");
    }
}

public static void ResponseCallback (IAsyncResult asyncResult)
{
    Console.WriteLine("Completed");
}

//call the timeout if more than 15 seconds

**public static void TimeoutCallback(object state, bool timedOut)
{
            if (timedOut)
            {
                HttpWebRequest request = state as HttpWebRequest;
                if (request != null)
                {
                    request.Abort();
                }
            }
}**

答案 1 :(得分:0)

我会将整个HTTP处理移动到Task并使用通用技术在该任务上设置超时。有许多这样的技术可供使用。

我不明白为什么你需要这么多个人超时。你不能只说:如果这个请求需要的时间超过4秒,不管是什么原因,请将其删除。

APM模式和等待事件是.NET 4.5和C#5时代的红旗。所有这些垃圾都掩盖了代码的意图。如果您使用await来使用WebRequest类提供的异步IO并使用围绕它的通用超时技术,那么垃圾就会消失。