C# 任务异步超时
我有一段代码来发出异步HTTP请求:C# 任务异步超时,c#,asynchronous,C#,Asynchronous,我有一段代码来发出异步HTTP请求: public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback) { WebRequest request = WebRequest.Create(uri); request.Proxy = null; Task.Factory.FromAsync<WebRespons
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();
});
}
从:
Timeout属性对使用BeginGetResponse或BeginGetRequestStream方法发出的异步请求没有影响
这是因为框架强制您自己处理超时。除了将从fromsync
调用返回的Task
传递到ThreadPool.RegisterWaitForSingleObject
方法之外,您应该能够使用
编辑: 您需要将注册放在原始任务上,而不是继续:
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();
});
}
publicstaticvoidmakerequest(Uri,Action-responseCallback)
{
WebRequest=WebRequest.Create(uri);
Proxy=null;
const int TimeoutPeriod=1000;
Task t=Task.Factory.fromsync(request.BeginGetResponse,request.EndGetResponse,null);
RegisterWaitForSingleObject((t作为IAsyncResult).AsyncWaitHandle,TimeoutCallback,request,TimeoutPeriod,true);
t、 继续(任务=>
{
WebResponse=task.Result;
Stream responseStream=response.GetResponseStream();
responseCallback(response.GetResponseStream());
responseStream.Close();
response.Close();
});
}
这对我来说是可行的(如果我将超时持续时间设置得很短,并点击此按钮,我总是会适当地超时)。正如您在问题中看到的,我更改了代码,但超时不起作用。我只收到一个timedOut为false的回调,之后什么也没发生。我无法让它工作。我有一个线程。主要方法是睡眠。这可能是问题所在吗?我更新了帖子,向你展示了我用来测试它的代码。它一开始只抛出一次timedOut false。我仍然被这个问题困扰@Reed你能帮我吗?你发布的代码对我无效。我用我所有的代码更新了这个问题(包括主代码)。你能看一下吗?谢谢你的帮助。@David:我回答了:答案和这里的一样,但要明确一点。这项技术很好用。。。
HttpSocket.MakeRequest(new Uri("http://www.google.comhklhlñ"), callbackState =>
{
if (callbackState.Exception != null)
throw callbackState.Exception;
Console.WriteLine(GetResponseText(callbackState.ResponseStream));
});
Thread.Sleep(10000);
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();
});
}