我有一个基于Mvx的iOS项目,该图像下载存在问题。

我有几个包含UICollectionViews的屏幕,UICollectionViewCells使用MvxDynamicImageHelpers将其UIImageViews的Image设置为Internet上托管的图像(实际上是通过Azure CDN的Azure Blob存储)。我注意到图像有时不显示,并且在连接缓慢时更常见,如果在加载图像时滚动整个UICollectionView,大概是因为它启动了大量的同时下载。重新启动应用程序会导致显示部分(而非全部)图像。

在Caches / Pictures.MvvmCross文件夹中查找,我看到有许多扩展名为.tmp的文件,有些没有.tmp扩展名,但文件大小为0字节。我认为.tmp文件是在应用程序重新启动后重新下载的文件,并且无效的内存中缓存条目导致它们在发生这种情况之前不会重新下载。

我已经实现了MvxDownloadRequest和MvxHttpFileDownloader的版本,并注册了IMvxHttpFileDownloader。 MvxHttpFileDownloader中的唯一修改是使用我的MvxDownloadRequest而不是标准Mvx。

据我所知,在MvxDownloadRequest.Start或MvxDownloadRequest.ProcessResponse和MvxDownloadRequest.FileDownloadFailed中没有引发任何异常。替换MvxDownloadRequest。从以下开始,所有图像始终会下载并成功显示:

        try
        {
            ThreadPool.QueueUserWorkItem((state) => {
                try
                {
                    var fileService = this.GetService<IMvxSimpleFileStoreService>();
                    var tempFilePath = DownloadPath + ".tmp";

                    var imageData = NSData.FromUrl(NSUrl.FromString(Url));

                    var image = UIImage.LoadFromData(imageData);

                    NSError nsError;
                    image.AsPNG().Save(tempFilePath, true, out nsError);

                    fileService.TryMove(tempFilePath, DownloadPath, true);
                }
                catch (Exception exception)
                {
                    FireDownloadFailed(exception);
                    return;
                }

                FireDownloadComplete();
            });
        }
        catch (Exception e)
        {
            FireDownloadFailed(e);
        }


那么,是什么导致标准WebRequest出现问题却又不影响上述版本?我猜测这与GC有关,并且在我有时间的时候会做进一步的调试,但是不幸的是这不会出现。如果有人可以回答这个问题或为我提供指导,我将不胜感激。

谢谢,

Ĵ

最佳答案

从到目前为止的调查描述来看,听起来您已经将问题隔离到了httpwebrequest有时失败的程度,但是NSData方法是100%可靠的。

如果是这种情况,则表明问题出在xamarin.ios网络堆栈中或在使用中。

可能值得检查xamarin bugzilla存储库,并询问他们的支持团队是否知道这一领域的任何问题。我相信他们确实在发展中宣布了有关iOS网络更改的公告-请参阅视频和http://xamarin.com/evolve/2013#session-b3mx6e6rmb幻灯片后面的CFNetworkHandler部分-此处还有诸如iPhone app gets into a state where network requests never complete之类的令人担忧的问题

除此之外,我猜想任何调试的第一步都是在一个简单的测试应用程序中找出问题,例如,一个简单的应用程序一次仅下载一个图像,并演示每种技术的简单通过/失败。如果您可以在小型测试应用程序中复制问题,那么找出问题根源会更快。

10-06 07:19