【发布时间】:2019-09-11 13:07:25
【问题描述】:
我正在尝试通过在响应中返回 MultiPartContent 从服务器加载大量数据。但是,在 HttpGet 方法期间,我设置的超时值被忽略。我正在尝试设置更长的超时时间,因为在这种情况下等待是可以的。
我尝试了 10 分钟到 2 小时之间的各种超时值。实际上,用户第一次使用我们的应用程序时只需要等待约 5 分钟,而其他时间则更少。 我还尝试存储 HttpClient 的引用,以确保 api.HttpClient 不会每次都重新创建 HttpClient 对象。
var handler = new HttpClientHandler();
var progress = new ProgressMessageHandler(handler);
var api = APIHelpers.GetSession(progress);
progress.HttpReceiveProgress += (e, args) => ProgressChanged.Invoke(e, new SyncEventArgs(GlobalEnums.SyncStage.Downloading, args.ProgressPercentage * 0.01f));
api.HttpClient.Timeout = new TimeSpan(0, 10, 0);
var downloadUri = BuildURI();
var response = await api.HttpClient.GetAsync(downloadUri, HttpCompletionOption.ResponseHeadersRead);
我希望应用程序在抛出 Timeout 异常之前等待 10 分钟,但是在 100 秒后抛出异常(我相信这是默认值?)。
设置后检查HttpClient.Timeout 值确实表明它设置正确。
APIHelpers.GetSession() 方法返回我们 API 的一个对象,其中创建了授权标头。 HttpClient 对象可通过继承类访问。这是由 Swashbuckle 和 Swagger 创建的。我之前曾以这种方式成功使用过api.HttpClient.Timeout = x,所以我认为这不是问题所在。它似乎特别针对这种情况。
抛出的异常:
{System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: The operation has timed out.
at System.Net.HttpWebRequest.RunWithTimeoutWorker[T] (System.Threading.Tasks.Task`1[TResult] workerTask, System.Int32 timeout, System.Action abort, System.Func`1[TResult] aborted, System.Threading.CancellationTokenSource cts) [0x000f8] in <a1ab7fc4639d4d84af41d68234158b1c>:0
at System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult) [0x00019] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/mcs/class/System/System.Net/HttpWebRequest.cs:1200
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (System.IAsyncResult iar, System.Func`2[T,TResult] endFunction, System.Action`1[T] endAction, System.Threading.Tasks.Task`1[TResult] promise, System.Boolean requiresSynchronization) [0x0000f] in <939d99b14d934342858948926287beba>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.MonoWebRequestHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x003d1] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/mcs/class/System.Net.Http/MonoWebRequestHandler.cs:499
--- End of inner exception stack trace ---
at System.Net.Http.MonoWebRequestHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x0046a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/mcs/class/System.Net.Http/MonoWebRequestHandler.cs:503
at Microsoft.Rest.RetryDelegatingHandler+<>c__DisplayClass11_0.<SendAsync>b__1 () [0x000ad] in <6a6c837cafbb4f1faffaba1ff30ca4e3>:0
at Microsoft.Rest.RetryDelegatingHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x00150] in <6a6c837cafbb4f1faffaba1ff30ca4e3>:0
at System.Net.Http.Handlers.ProgressMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x00087] in <19af20e76ce04547b3fc150a0f8f2d47>:0
at System.Net.Http.HttpClient.SendAsyncWorker (System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) [0x0009e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:281
at ...
编辑: 我只是添加了一些我尝试过的其他东西来解决这个问题。
- 我尝试使用 Xamarin.Forms 中的 DependencyService 来获取每个平台的本机
HttpClientHandlers和HttpClient对象,我可以在其中设置每个平台的超时时间,而不是依靠Xamarin.Forms为我翻译它。这具有完全相同的结果。
public HttpMessageHandler GetHttpHandler(double timeoutSeconds)
{
var sessionConfig = NSUrlSessionConfiguration.DefaultSessionConfiguration;
sessionConfig.TimeoutIntervalForRequest = timeoutSeconds;
sessionConfig.TimeoutIntervalForResource = timeoutSeconds;
sessionConfig.WaitsForConnectivity = true;
var sessionHandler = new NSUrlSessionHandler(sessionConfig);
return sessionHandler;
}
- 我已经尝试为这个 API 调用创建一个新的
HttpClient对象,但这里也没有运气。 (这将替换我代码中的Apihelpers.GetSession())
【问题讨论】:
-
api.HttpClient属性是如何定义的?是不是每次访问都会创建一个新的HttpClient? -
另外,你说的是“超时异常”,但是当达到超时时
HttpClient会抛出一个TaskCancelledException。这是你看到的例外吗? -
@GabrielLuci 我在原始帖子中写道,我已经尝试存储 HttpClient 对象以确保它不会每次都重新创建它并且不起作用。我已编辑我的帖子以包含例外情况
-
哪个平台? iOS 还是|和 Android?
-
@SushiHangover iOS 和 Android 都有同样的问题。上述例外来自 iOS
标签: c# .net xamarin httpclient