任务fromAsync超时 [英] Task fromAsync timeout
问题描述
我有这块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 theFromAsync
call to theThreadPool.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屋!