// TODO (CR Apr 2013): the reason this is overloaded is because there's not always a task to return. Would be better // to return some other object, possibly with the task as a property, but also with the volume itself, if it's available. private Task LoadAsync(VolumeLoadProgressCallback onProgress = null, VolumeLoadCompletionCallback onComplete = null, VolumeLoadErrorCallback onError = null) { AssertNotDisposed(); // TODO (CR Apr 2013): Not a good idea to return nothing; why not return a struct with the volume in it? if (_volumeReference != null) { return(null); } if (_backgroundLoadTask != null) { return(_backgroundLoadTask); } lock (_backgroundLoadSyncRoot) { if (_volumeReference != null) { return(null); } if (_backgroundLoadTask != null) { return(_backgroundLoadTask); } _backgroundLoadTask = new Task(() => LoadCore(onProgress)); _backgroundLoadTask.ContinueWith(t => { // TODO (CR Apr 2013): Can probably just lock the part that // changes the _backgroundLoadTask variable. lock (_backgroundLoadSyncRoot) { if (t.IsFaulted && t.Exception != null) { var ex = t.Exception.Flatten().InnerExceptions.FirstOrDefault(); if (onError != null) { onError.Invoke(this, ex); } else { Platform.Log(LogLevel.Warn, ex, "Unhandled exception thrown in background volume loader"); } } else { if (onComplete != null) { onComplete.Invoke(this); } } if (ReferenceEquals(t, _backgroundLoadTask)) { _backgroundLoadTask.Dispose(); _backgroundLoadTask = null; } } }); _backgroundLoadTask.Start(); return(_backgroundLoadTask); } }
// TODO (CR Apr 2013): API is a bit overloaded; the task provides completion and error info already // so probably all that is needed is the progress callback argument. public Task LoadAsync(VolumeLoadProgressCallback onProgress = null, VolumeLoadCompletionCallback onComplete = null, VolumeLoadErrorCallback onError = null) { return(_cachedVolume.LoadAsync(onProgress, onComplete, onError)); }
private IAsyncResult LoadAsync(VolumeLoadProgressCallback onProgress = null, VolumeLoadCompletionCallback onComplete = null, VolumeLoadErrorCallback onError = null) { AssertNotDisposed(); if (_volumeReference != null) { return(null); } if (_backgroundLoadMethod != null) { return(_backgroundLoadMethodAsyncResult); } lock (_backgroundLoadSyncRoot) { if (_volumeReference != null) { return(null); } if (_backgroundLoadMethod != null) { return(_backgroundLoadMethodAsyncResult); } _backgroundLoadMethod = () => { try { LoadCore(onProgress); if (onComplete != null) { onComplete.Invoke(this); } } catch (Exception ex) { if (onError != null) { onError.Invoke(this, ex); } else { Platform.Log(LogLevel.Debug, ex, "Unhandled exception thrown in asynchronous volume loader"); } } }; return(_backgroundLoadMethodAsyncResult = _backgroundLoadMethod.BeginInvoke(ar => { _backgroundLoadMethod.EndInvoke(ar); _backgroundLoadMethod = null; _backgroundLoadMethodAsyncResult = null; }, null)); } }