Esempio n. 1
0
            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));
                }
            }
Esempio n. 2
0
            private Volume LoadCore(VolumeLoadProgressCallback callback)
            {
                // TODO (CR Apr 2013): Same comment as with Fusion - shouldn't actually need to lock for
                // the duration of volume creation. Should be enough to set a _loading flag, exit the lock,
                // then re-enter the lock to reset the _loading flag and set any necessary fields.
                // Locking for the duration means the memory manager could get hung up while trying to unload
                // a big volume that is in the process of being created.

                lock (_syncRoot)
                {
                    if (_volumeReference != null)
                    {
                        return(_volumeReference.Volume);
                    }

                    Progress = 0;

                    using (var volume = Volume.Create(_frames, (n, total) =>
                    {
                        Progress = Math.Min(100f, 100f * n / total);
                        if (callback != null)
                        {
                            callback.Invoke(this, n, total);
                        }
                        _largeObjectContainerData.UpdateLastAccessTime();

#if UNIT_TESTS
                        if (ThrowAsyncVolumeLoadException)
                        {
                            ThrowAsyncVolumeLoadException = false;
                            throw new CreateVolumeException("User manually triggered exception");
                        }
#endif
                    }))
                    {
                        _volumeReference = volume.CreateReference();

                        _largeObjectContainerData.LargeObjectCount = 1;
                        _largeObjectContainerData.BytesHeldCount   = 2 * volume.ArrayLength;
                        _largeObjectContainerData.UpdateLastAccessTime();
                        MemoryManager.Add(this);
                    }

                    Progress = 100f;

                    return(_volumeReference.Volume);
                }
            }
Esempio n. 3
0
            private Volume LoadCore(VolumeLoadProgressCallback callback)
            {
                if (_volumeReference != null)
                {
                    return(_volumeReference.Volume);
                }

                lock (_syncRoot)
                {
                    if (_volumeReference != null)
                    {
                        return(_volumeReference.Volume);
                    }

                    Progress = 0;

                    using (var volume = Volume.Create(_frames, (n, total) =>
                    {
                        Progress = Math.Min(100f, 100f * n / total);
                        if (callback != null)
                        {
                            callback.Invoke(this, n, total);
                        }
                    }))
                    {
                        _volumeReference = volume.CreateTransientReference();

                        _largeObjectContainerData.LargeObjectCount = 1;
                        _largeObjectContainerData.BytesHeldCount   = 2 * volume.SizeInVoxels;
                        _largeObjectContainerData.UpdateLastAccessTime();
                        MemoryManager.Add(this);
                    }

                    Progress = 100f;

                    return(_volumeReference.Volume);
                }
            }
Esempio n. 4
0
 public void Load(VolumeLoadProgressCallback callback = null)
 {
     _cachedVolume.Load(callback);
 }
Esempio n. 5
0
 // 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));
 }
Esempio n. 6
0
            // 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);
                }
            }
Esempio n. 7
0
 private void Load(VolumeLoadProgressCallback callback = null)
 {
     AssertNotDisposed();
     LoadCore(callback);
 }