任务fromAsync超时 [英] Task fromAsync timeout

查看:262
本文介绍了任务fromAsync超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这块code,使异步HTTP请求:

 公共静态无效makeRequest的(URI URI,动作< RequestCallbackState> responseCallback)
    {
        WebRequest的请求= WebRequest.Create(URI);
        request.Proxy = NULL;        Task.Factory.FromAsync<&WebResponse的GT;(request.BeginGetResponse,request.EndGetResponse,NULL).ContinueWith(任务=>
            {
                WebResponse的响应= task.Result;
                流responseStream = response.GetResponseStream();
                responseCallback(新RequestCallbackState(response.GetResponseStream()));
                responseStream.Close();
                response.Close();
            });
    }

它的工作原理,但我需要设置一个请求超时。我试图用request.Timeout,但似乎并没有做任何事情。有没有办法建立一个任务超时在这个code?

编辑补充一个新的超时回调。
新的code:

 公共静态无效makeRequest的(URI URI,动作< RequestCallbackState> responseCallback)
    {
        WebRequest的请求= WebRequest.Create(URI);
        request.Proxy = NULL;        IAsyncResult的T = Task.Factory.FromAsync<&WebResponse的GT;(request.BeginGetResponse,request.EndGetResponse,NULL).ContinueWith(任务=>
            {
                WebResponse的响应= task.Result;
                流responseStream = response.GetResponseStream();
                responseCallback(新RequestCallbackState(response.GetResponseStream()));
                responseStream.Close();
                response.Close();
            });
        ThreadPool.RegisterWaitForSingleObject(t.AsyncWaitHandle,新WaitOrTimerCallback(TimeoutCallback)的要求,1000年,真正的);
    }    私有静态无效TimeoutCallback(对象状态,布尔TIMEDOUT)
    {
        如果(TIMEDOUT)
        {
            Console.WriteLine(超时);
            WebRequest的要求=(WebRequest的)状态;
            如果(状态!= NULL)
            {
                request.Abort();
            }
        }
    }

与测试:

  HttpSocket.MakeRequest(新的URI(HTTP://www.google.comhklhlñ),callbackState =>
    {
        如果(callbackState.Exception!= NULL)
            扔callbackState.Exception;
        Console.WriteLine(GetResponseText(callbackState.ResponseStream));
    });
Thread.sleep代码(10000);


解决方案

从的超时文档


  

超时属性对与BeginGetResponse或BeginGetRequestStream方法进行异步请求没有影响。


这是因为框架迫使你自己处理超时。你应该可以使用example code这里,除了通过工作从返回的 FromAsync 打电话到 ThreadPool.RegisterWaitForSingleObject 方法。


编辑:

您需要把登记的原始任务,而不是延续:

 公共静态无效makeRequest的(URI URI,动作<流> responseCallback)
{
    WebRequest的请求= WebRequest.Create(URI);
    request.Proxy = NULL;
    const int的TimeoutPeriod = 1000;    任务<&WebResponse的GT; T = Task.Factory.FromAsync<&WebResponse的GT;(request.BeginGetResponse,request.EndGetResponse,NULL);
    ThreadPool.RegisterWaitForSingleObject((T为IAsyncResult的).AsyncWaitHandle,TimeoutCallback,请求,TimeoutPeriod,真正的);
    t.ContinueWith(任务=>
    {
        WebResponse的响应= task.Result;
        流responseStream = response.GetResponseStream();
        responseCallback(response.GetResponseStream());
        responseStream.Close();
        response.Close();
    });
}

这对我的作品(如果我设置超时时间非常短,打这个,我总是超时适当)。

I have this piece of code to make an asynchronous HTTP request:

    public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback)
    {
        WebRequest request = WebRequest.Create(uri);
        request.Proxy = null;

        Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ContinueWith(task =>
            {
                WebResponse response = task.Result;
                Stream responseStream = response.GetResponseStream();
                responseCallback(new RequestCallbackState(response.GetResponseStream()));
                responseStream.Close();
                response.Close();
            });
    }

It works, but I need to set a request timeout. I tried to use request.Timeout but don't seem to do anything. Is there a way to set up a task timeout in this code?

Edited to add a new timeout callback. New code:

    public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback)
    {
        WebRequest request = WebRequest.Create(uri);
        request.Proxy = null;

        IAsyncResult t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ContinueWith(task =>
            {
                WebResponse response = task.Result;
                Stream responseStream = response.GetResponseStream();
                responseCallback(new RequestCallbackState(response.GetResponseStream()));
                responseStream.Close();
                response.Close();
            });
        ThreadPool.RegisterWaitForSingleObject(t.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, 1000, true);
    }

    private static void TimeoutCallback(object state, bool timedOut)
    {
        if (timedOut)
        {
            Console.WriteLine("Timeout");
            WebRequest request = (WebRequest)state;
            if (state != null)
            {
                request.Abort();
            }
        }
    }

Testing with:

HttpSocket.MakeRequest(new Uri("http://www.google.comhklhlñ"), callbackState =>
    {
        if (callbackState.Exception != null)
            throw callbackState.Exception;
        Console.WriteLine(GetResponseText(callbackState.ResponseStream));
    });
Thread.Sleep(10000);

解决方案

From the Timeout documentation:

The Timeout property has no effect on asynchronous requests made with the BeginGetResponse or BeginGetRequestStream method.

This is because the framework forces you to handle the timeout yourself. You should be able to use the example code here, except pass the Task returned from the FromAsync call to the ThreadPool.RegisterWaitForSingleObject method.


Edit:

You need to put the registration on the original task, not the continuation:

public static void MakeRequest(Uri uri, Action<Stream> responseCallback)
{
    WebRequest request = WebRequest.Create(uri);
    request.Proxy = null;
    const int TimeoutPeriod = 1000;

    Task<WebResponse> t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
    ThreadPool.RegisterWaitForSingleObject((t as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, TimeoutPeriod, true);
    t.ContinueWith(task =>
    {
        WebResponse response = task.Result;
        Stream responseStream = response.GetResponseStream();
        responseCallback(response.GetResponseStream());
        responseStream.Close();
        response.Close();
    });
}

This works for me (if I set the timeout duration very short, and hit this, I always timeout appropriately).

这篇关于任务fromAsync超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆