private void WithCancelToken(CancellationToken token, Action <GCHandle> action)
        {
            var cancelTokenHandle = GCHandle.Alloc(token, GCHandleType.Pinned);

            try
            {
                action(cancelTokenHandle);
            }
            catch (Exception ex)
            {
                _trace.Error(TraceCategory, ex, "Cannot execute.");
            }
            finally
            {
                cancelTokenHandle.Free();
            }
        }
        /// <inheritdoc />
        public IObservable <int> AddTo(string storageKey, string path, Stylesheet stylesheet, Range <int> levelOfDetails, CancellationToken cancellationToken)
        {
            var dataPath  = _pathResolver.Resolve(path);
            var stylePath = RegisterStylesheet(stylesheet);

            _trace.Debug(TraceCategory, "Add data from {0} to {1} storage", dataPath, storageKey);
            lock (__lockObj)
            {
                WithCancelToken(cancellationToken, (cancelTokenHandle) => addDataInRange(
                                    storageKey, stylePath, dataPath, levelOfDetails.Minimum,
                                    levelOfDetails.Maximum, OnErrorHandler, cancelTokenHandle.AddrOfPinnedObject()));
            }
            return(Observable.Return <int>(100));
        }
        /// <inheritdoc />
        public IObservable <int> AddTo(string storageKey, Element element, Stylesheet stylesheet, Range <int> levelOfDetails, CancellationToken cancellationToken)
        {
            _trace.Debug(TraceCategory, "Add element to {0} storage", storageKey);
            double[] coordinates = new double[element.Geometry.Length * 2];
            for (int i = 0; i < element.Geometry.Length; ++i)
            {
                coordinates[i * 2]     = element.Geometry[i].Latitude;
                coordinates[i * 2 + 1] = element.Geometry[i].Longitude;
            }

            string[] tags    = new string[element.Tags.Count * 2];
            var      tagKeys = element.Tags.Keys.ToArray();

            for (int i = 0; i < tagKeys.Length; ++i)
            {
                tags[i * 2]     = tagKeys[i];
                tags[i * 2 + 1] = element.Tags[tagKeys[i]];
            }

            var stylePath = RegisterStylesheet(stylesheet);

            lock (__lockObj)
            {
                WithCancelToken(cancellationToken, (cancelTokenHandle) => addDataInElement(
                                    storageKey, stylePath, element.Id, coordinates, coordinates.Length, tags, tags.Length,
                                    levelOfDetails.Minimum, levelOfDetails.Maximum, OnErrorHandler, cancelTokenHandle.AddrOfPinnedObject()));
            }
            return(Observable.Return <int>(100));
        }
        /// <inheritdoc />
        public UtyRx.IObservable <int> AddTo(string storageKey, string path, Stylesheet stylesheet, QuadKey quadKey, CancellationToken cancellationToken)
        {
            var dataPath  = _pathResolver.Resolve(path);
            var stylePath = RegisterStylesheet(stylesheet);

            _trace.Debug(TraceCategory, "Add data from {0} to {1} storage", dataPath, storageKey);
            lock (__lockObj)
            {
                WithCancelToken(cancellationToken, (cancelTokenHandle) => addDataInQuadKey(
                                    storageKey, stylePath, dataPath, quadKey.TileX, quadKey.TileY,
                                    quadKey.LevelOfDetail, OnErrorHandler, cancelTokenHandle.AddrOfPinnedObject()));
            }
            return(Observable.Return <int>(100));
        }