private async Task PrefetchAsyncInternal() { Utils.AssertMainThread(); try { // allow the task to be saved to the object; await TaskEx.Yield(); #if !STANDALONE if (Caching.AzureApi != null) { var url = new LazyUri(Url); var container = Caching.GetAzureContainer(url); var files = await Caching.GetAzureCachedFiles(container); var name = Caching.GetFileCachePath(url); if (files.Contains(name)) { return; } try { await Caching.AzureApi.UploadAzureFileAsync(container, name, this); } finally { files.Add(name); } return; } #endif var path = Caching.GetFileCachePath(new LazyUri(Url), true); if (path == null) { throw new InvalidOperationException("Caching.FileCachePath must be configured for file prefetching to work."); } if (File.Exists(path)) { return; } var folder = Path.GetDirectoryName(path); using (var c = new FileStream(path + "$", FileMode.Create, FileAccess.Write, FileShare.Delete)) { try { using (var s = await OpenStreamAsync()) { await s.CopyToAsync(c); } } catch (Exception ex) { lock (this) { c.SetLength(0); c.Dispose(); File.WriteAllText(Path.ChangeExtension(path, ".err"), GetExceptionSummary(ex), Encoding.UTF8); File.Delete(path); File.Move(path + "$", path); return; } } } lock (this) { File.Delete(path); File.Move(path + "$", path); File.Delete(Path.ChangeExtension(path, ".err")); } } finally { prefetchingTask = null; } }
internal async Task <Stream> OpenStreamAsync(bool synchronous, bool skipCache = false, bool linger = true) { var url = new LazyUri(Url); await Utils.CheckLocalFileAccessAsync(url); var mgr = this.manager; Func <long, Task <HttpResponseMessage> > createStream = null; #if !STANDALONE && DESKTOP if (Caching.AzureApi != null && (mgr == null || !mgr.IsAlive) && !skipCache) { var container = Caching.GetAzureContainer(url); HashSet <string> files = null; if (synchronous) { ObjectManager.SynchronizationContext.Send(async() => { files = await Caching.GetAzureCachedFiles(container); }); } else { await ObjectManager.SynchronizationContext.SendAsync(async() => { files = await Caching.GetAzureCachedFiles(container); }); } var name = Caching.GetFileCachePath(url); if (files.Contains(name)) { createStream = offset => Caching.GetAzureResponseAsync(container, name, offset, this); } } else #endif if ( #if !STANDALONE && DESKTOP Caching.AzureApi == null && #endif !skipCache) { #if DESKTOP var cache = Caching.GetFileCachePath(url); if (File.Exists(cache)) { var str = new FileStream(cache, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete); if (str.Length == 0) { var errfile = Path.ChangeExtension(cache, ".err"); if (File.Exists(errfile)) { str.Dispose(); var errlines = File.ReadAllText(errfile); return(new MediaStream(MediaStream.ExceptionFromCachedResponse(errlines), this)); } } Sanity.AssertFastReadByte(str); return(str); } #endif } lock (this) { if (manager == null) { manager = new MediaStreamManager(createStream ?? GetResponseAsync, true); } var stream = manager.TryCreateStream(this, 0, linger); if (stream == null) { manager = new MediaStreamManager(createStream ?? GetResponseAsync, true); stream = manager.TryCreateStream(this, 0, linger); Sanity.Assert(stream != null); } Sanity.AssertFastReadByte(stream); return(stream); } }