gpt4 book ai didi

c# - 异步任务超时

转载 作者:太空狗 更新时间:2023-10-29 22:54:20 25 4
gpt4 key购买 nike

我有这段代码可以发出异步 HTTP 请求:

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

有效,但我需要设置请求超时。我尝试使用 request.Timeout 但似乎什么也没做。有没有办法在此代码中设置任务超时?

编辑以添加新的超时回调。新代码:

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

测试:

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

最佳答案

来自Timeout documentation :

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

这是因为框架强制你自己处理超时。您应该能够使用 example code here ,除了将从 FromAsync 调用返回的 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();
});
}

这对我有用(如果我将超时持续时间设置得非常短,然后点击它,我总是会适本地超时)。

关于c# - 异步任务超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7368737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com