diff --git a/source/FFImageLoading.Common/Config/Configuration.cs b/source/FFImageLoading.Common/Config/Configuration.cs index 4f62477a6..c37ea3719 100644 --- a/source/FFImageLoading.Common/Config/Configuration.cs +++ b/source/FFImageLoading.Common/Config/Configuration.cs @@ -28,6 +28,7 @@ public Configuration() VerboseLoadingCancelledLogging = false; VerboseLogging = false; SchedulerMaxParallelTasks = Math.Max(2, (int)(Environment.ProcessorCount / 2d)); + DiskCacheDuration = TimeSpan.FromDays(30d); } /// @@ -151,6 +152,12 @@ public Configuration() /// /// The scheduler max parallel tasks. public int SchedulerMaxParallelTasks { get; set; } + + /// + /// Gets or sets the default duration of the disk cache entries. + /// + /// The duration of the cache. + public TimeSpan DiskCacheDuration { get; set; } } } diff --git a/source/FFImageLoading.Common/Work/DownloadInformation.cs b/source/FFImageLoading.Common/Work/DownloadInformation.cs index 14772bd10..d1380f00b 100644 --- a/source/FFImageLoading.Common/Work/DownloadInformation.cs +++ b/source/FFImageLoading.Common/Work/DownloadInformation.cs @@ -7,7 +7,7 @@ public DownloadInformation(string url, string customCacheKey, string fileName, b { Url = url; CustomCacheKey = customCacheKey; - FileName = fileName?.ToSanitizedKey(); + FileName = fileName; AllowDiskCaching = allowDiskCaching; CacheValidity = cacheValidity; } diff --git a/source/FFImageLoading.Forms/CachedImage.cs b/source/FFImageLoading.Forms/CachedImage.cs index b54426004..cd20ab780 100644 --- a/source/FFImageLoading.Forms/CachedImage.cs +++ b/source/FFImageLoading.Forms/CachedImage.cs @@ -264,7 +264,7 @@ public bool DownsampleUseDipUnits /// /// The cache duration property. /// - public static readonly BindableProperty CacheDurationProperty = BindableProperty.Create(nameof(CacheDuration), typeof(TimeSpan), typeof(CachedImage), TimeSpan.FromDays(90)); + public static readonly BindableProperty CacheDurationProperty = BindableProperty.Create(nameof(CacheDuration), typeof(TimeSpan), typeof(CachedImage), default(TimeSpan)); /// /// How long the file will be cached on disk. diff --git a/source/FFImageLoading.Shared/Cache/DownloadCache.cs b/source/FFImageLoading.Shared/Cache/DownloadCache.cs index 4d900bfce..71c23fd2f 100644 --- a/source/FFImageLoading.Shared/Cache/DownloadCache.cs +++ b/source/FFImageLoading.Shared/Cache/DownloadCache.cs @@ -11,28 +11,30 @@ public class DownloadCache: IDownloadCache { private readonly MD5Helper _md5Helper; private readonly IDiskCache _diskCache; + private readonly TimeSpan _diskCacheDuration; private const int BufferSize = 4096; // Xamarin large object heap threshold is 8K - public DownloadCache(HttpClient httpClient, IDiskCache diskCache) + public DownloadCache(HttpClient httpClient, IDiskCache diskCache, TimeSpan diskCacheDuration) { DownloadHttpClient = httpClient; _md5Helper = new MD5Helper(); _diskCache = diskCache; + _diskCacheDuration = diskCacheDuration; } public HttpClient DownloadHttpClient { get; set; } public async Task GetDiskCacheFilePathAsync(string url, string key = null) { - string filename = string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key); - return await _diskCache.GetFilePathAsync(filename); + string filename = (string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key))?.ToSanitizedKey(); + return await _diskCache.GetFilePathAsync(filename).ConfigureAwait(false); } public async Task GetAsync(string url, CancellationToken token, Action onDownloadStarted, TimeSpan? duration = null, string key = null, CacheType? cacheType = null) { - string filename = string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key); + string filename = (string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key))?.ToSanitizedKey(); var allowDiskCaching = AllowDiskCaching(cacheType); - string filepath = allowDiskCaching == false ? null : await _diskCache.GetFilePathAsync(filename); + string filepath = allowDiskCaching == false ? null : await _diskCache.GetFilePathAsync(filename).ConfigureAwait(false); if (allowDiskCaching) { @@ -50,9 +52,8 @@ public async Task GetAsync(string url, CancellationToken token, public async Task GetStreamAsync(string url, CancellationToken token, Action onDownloadStarted, TimeSpan? duration = null, string key = null, CacheType? cacheType = null) { - string filename = string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key); + string filename = (string.IsNullOrWhiteSpace(key) ? _md5Helper.MD5(url) : _md5Helper.MD5(key))?.ToSanitizedKey(); var allowDiskCaching = AllowDiskCaching(cacheType); - // string filepath = allowDiskCaching == false ? null : await _diskCache.GetFilePathAsync(filename); if (allowDiskCaching) { @@ -80,7 +81,7 @@ private async Task DownloadStreamAndCacheAsync(string url, string var allowDiskCaching = AllowDiskCaching(cacheType); if (allowDiskCaching) { - await _diskCache.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, duration ?? new TimeSpan(30, 0, 0, 0)); // by default we cache data 30 days) + await _diskCache.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, duration ?? _diskCacheDuration).ConfigureAwait(false); } return memoryStream; @@ -95,7 +96,7 @@ private async Task DownloadBytesAndCacheAsync(string url, string filenam var allowDiskCaching = AllowDiskCaching(cacheType); if (allowDiskCaching) { - await _diskCache.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, duration ?? new TimeSpan(30, 0, 0, 0)); // by default we cache data 30 days) + await _diskCache.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, duration ?? _diskCacheDuration).ConfigureAwait(false); } return responseBytes; @@ -106,6 +107,7 @@ private async Task DownloadAsync(string url, string filename, Cancellati using (var cancelHeadersToken = new CancellationTokenSource()) { cancelHeadersToken.CancelAfter(TimeSpan.FromSeconds(ImageService.Instance.Config.HttpHeadersTimeout)); + using (var linkedHeadersToken = CancellationTokenSource.CreateLinkedTokenSource(token, cancelHeadersToken.Token)) { using (var response = await DownloadHttpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, linkedHeadersToken.Token).ConfigureAwait(false)) diff --git a/source/FFImageLoading.Shared/ImageService.cs b/source/FFImageLoading.Shared/ImageService.cs index 49f50dd32..5d656232f 100644 --- a/source/FFImageLoading.Shared/ImageService.cs +++ b/source/FFImageLoading.Shared/ImageService.cs @@ -123,7 +123,7 @@ private void InitializeIfNeeded(Configuration userDefinedConfig = null) var logger = new MiniLoggerWrapper(userDefinedConfig.Logger ?? new MiniLogger(), userDefinedConfig.VerboseLogging); var scheduler = userDefinedConfig.Scheduler ?? new WorkScheduler(logger, userDefinedConfig.VerbosePerformanceLogging, new PlatformPerformance(), userDefinedConfig.SchedulerMaxParallelTasks); var diskCache = userDefinedConfig.DiskCache ?? SimpleDiskCache.CreateCache("FFSimpleDiskCache"); - var downloadCache = userDefinedConfig.DownloadCache ?? new DownloadCache(httpClient, diskCache); + var downloadCache = userDefinedConfig.DownloadCache ?? new DownloadCache(httpClient, diskCache, userDefinedConfig.DiskCacheDuration); userDefinedConfig.HttpClient = httpClient; userDefinedConfig.Scheduler = scheduler;