我已经将这段代码用于生产很长一段时间了,这个问题才刚刚开始。基本上它是从MVC控制器下载文件。这些文件大约是5到20兆字节。这是一个在iOS上运行的PCL库。用户从服务器下载文件时收到错误。我假设它是暂停,但我不是100%肯定。我们无法在内部重新创建此问题,但我们看到日志中的错误和用户已报告此情况。
我可以在服务器端做些什么来改善这个?客户端没有任何变化,它已成为我们客户群的普遍问题。
服务器代码
public virtual FileResult BuildDatabaseForSite(Guid organizationId, Guid siteId) {
var basePath = RESTContext.Config.DBPath;
var filePath = basePath + @"\" + fileId + ".db";
byte[] existingDbBytes = null;
using (new Impersonator(RESTContext.Config.VideoPathUsername, RESTContext.Config.VideoPathDomain,
RESTContext.Config.VideoPathPassword)) {
if (System.IO.File.Exists(filePath))
existingDbBytes = System.IO.File.ReadAllBytes(filePath);
}
return File(existingDbBytes, "application/octet-stream", "CompassLocal.db");
}
客户代码
public void DownloadDatabase(Guid organizationId, Guid siteId) {
Platform.FileSystem.DeleteFile(Paths.LocalDatabase);
var url = string.Format("organizations/{0}/Sites/{1}/InitialDatabaseCompressed", organizationId, siteId);
var webClient = new HttpClient();
webClient.Timeout = new TimeSpan(0,0,5,0);
webClient.DefaultRequestHeaders.Add("Authorization", authHeader);
var stream = webClient.GetStreamAsync(url).Result;
using (Stream file = File.OpenWrite(Paths.LocalDatabase)) {
stream.CopyTo(file);
}
}
堆栈跟踪
System.AggregateException: One or more errors occurred
at System.Threading.Tasks.Task.Wait (Int32 millisecondsTimeout, CancellationToken cancellationToken) [0x00000] in <filename unknown>:0
at System.Threading.Tasks.Task.Wait () [0x00000] in <filename unknown>:0
at System.Threading.Tasks.Task`1[TResult].get_Result () [0x00000] in <filename unknown>:0
at DataFinch.Mobile.Core.Network.RemoteAPI.DownloadDatabase (Guid organizationId, Guid siteId) [0x00000] in <filename unknown>:0
at DataFinch.Mobile.Core.Services.Registration.RegistrationService.RegisterDeviceAndDownloadDatabase (System.String username, System.String password, Guid siteId) [0x00000] in <filename unknown>:0
答案 0 :(得分:1)
显然这是由超时引起的 - 毕竟,堆栈跟踪指示异常发生在Task.Wait(...)
- 这是由任务的Result
属性在调用堆栈的内部调用。
因为这发生在客户端,所以在服务器端没有什么可以做的。您可以尝试以某种方式使服务器更快。但我怀疑这会有所帮助,因为移动客户端的可用带宽仍然有限 - 而且还有更多:这取决于每个客户的数据计划。
无论如何,因为您可以(并且您将)始终拥有带宽非常差的客户,因此文件大小通常太大而无法定位移动客户端。您所能做的就是为下一版本的应用程序安排下载逻辑的重构,将您的下载分成更小的块,并使您的客户端代码尽可能地处理这些类型的问题...
此外,在等待如此大的下载时阻塞整个线程,即使它是一个工作线程也是一个坏主意(特别是在没有可用带宽指示的移动客户端上)。这导致线程在很长一段时间内没有响应。你也应该考虑改变这种逻辑。