//TODO (CR Sept 2010): same comment as with the ProgressGraphic stuff; the API is unclear //as to what it is doing (return value) because it's trying to account for the async loading. /// <summary> /// Attempts to start loading the overlay data asynchronously, if not already loaded. /// </summary> /// <param name="progress">A value between 0 and 1 indicating the progress of the asynchronous loading operation.</param> /// <param name="message">A string message detailing the progress of the asynchronous loading operation.</param> /// <returns></returns> public bool BeginLoad(out float progress, out string message) { // update the last access time _largeObjectData.UpdateLastAccessTime(); // if the data is already available without blocking, return success immediately //TODO (CR Sept 2010): because unloading the volume involves disposing it, if every operation that uses it //isn't in the same lock (e.g. lock(_syncVolumeDataLock)) you could be getting a disposed/null volume here. VolumeData volume = _volume; if (volume != null) { message = SR.MessageFusionComplete; progress = 1f; return(true); } lock (_syncLoaderLock) { message = SR.MessageFusionInProgress; progress = 0; if (_volumeLoaderTask == null) { // if the data is available now, return success volume = _volume; if (volume != null) { message = SR.MessageFusionComplete; progress = 1f; return(true); } _volumeLoaderTask = new BackgroundTask(c => this.LoadVolume(c), false, null) { ThreadUICulture = Application.CurrentUICulture }; _volumeLoaderTask.Run(); _volumeLoaderTask.Terminated += OnVolumeLoaderTaskTerminated; } else { if (_volumeLoaderTask.LastBackgroundTaskProgress != null) { message = _volumeLoaderTask.LastBackgroundTaskProgress.Progress.Message; progress = _volumeLoaderTask.LastBackgroundTaskProgress.Progress.Percent / 100f; } } } return(false); }
private void UnloadVolume() { // wait for synchronized access lock (_syncVolumeDataLock) { // dump our data if (_volume != null) { _volume.Dispose(); _volume = null; } // update our stats _largeObjectData.BytesHeldCount = 0; _largeObjectData.LargeObjectCount = 0; // unregister with memory manager MemoryManager.Remove(this); } this.OnUnloaded(); }
private VolumeData LoadVolume(IBackgroundTaskContext context) { // wait for synchronized access lock (_syncVolumeDataLock) { // if the data is now available, return it immediately // (i.e. we were blocked because we were already reading the data) if (_volume != null) { return(_volume); } // load the volume data if (context == null) { _volume = VolumeData.Create(_frames); } else { _volume = VolumeData.Create(_frames, (n, count) => context.ReportProgress(new BackgroundTaskProgress(n, count, SR.MessageFusionInProgress))); } // update our stats _largeObjectData.BytesHeldCount = 2 * _volume.SizeInVoxels; _largeObjectData.LargeObjectCount = 1; _largeObjectData.UpdateLastAccessTime(); // regenerating the volume data is easy when the source frames are already in memory! _largeObjectData.RegenerationCost = RegenerationCost.Low; // register with memory manager MemoryManager.Add(this); return(_volume); } }