コード例 #1
0
        public IObservable<Unit> Fetch (Request request)
        {
            return Observable.Create<Unit> (o => {
                var description = request.DescriptionAs<ScaledDescription> ();
                var url = new NSUrl (description.AbsoluteSourceUrl.AbsoluteUri);
                var disp = new CancellationDisposable ();
                var token = disp.Token;

                Task.Factory.StartNew (() => {
                    using (var source = CGImageSource.FromUrl (url)) {
                        if (source.Handle == IntPtr.Zero)
                            throw new Exception (string.Format ("Could not create source for '{0}'", url));

                        var sourceSize = ImageHelper.Measure (source);
                        int maxPixelSize = GetMaxPixelSize (sourceSize, description.Size);

                        using (var scaled = CreateThumbnail (source, maxPixelSize, token))
                        using (var cropped = ScaleAndCrop (scaled, description.Size, description.Mode, token))
                            SaveToRequest (cropped, source.TypeIdentifier, request);

                        o.OnCompleted ();
                    }
                }, token).RouteExceptions (o);

                return disp;
            });
        }
コード例 #2
0
        private static IDisposable ScheduledMethod(IObserver<int> o)
        {
            var cancel = new CancellationDisposable();
            // internally creates a new CancellationTokenSource
            NewThreadScheduler.Default.Schedule(() =>
                                                    {
                                                        int i = 0;
                                                        for (;;)
                                                        {
                                                            Thread.Sleep(200);
                                                            // here we do the long lasting background operation
                                                            if (!cancel.Token.IsCancellationRequested)
                                                                // check cancel token periodically
                                                                o.OnNext(i++);
                                                            else
                                                            {
                                                                Console.WriteLine(
                                                                    "Aborting because cancel event was signaled!");
                                                                o.OnCompleted();
                                                                return;
                                                            }
                                                        }
                                                    }
                );

            return cancel;
        }
コード例 #3
0
        public static void CancelingAnAsynchronousOperation()
        {
            IObservable<int> ob =
                Observable.Create<int>(o =>
                {
                    var cancel = new CancellationDisposable(); // internally creates a new CancellationTokenSource
                    NewThreadScheduler.Default.Schedule(() =>
                    {
                        int i = 0;
                        for (;;)
                        {
                            Thread.Sleep(200); // here we do the long lasting background operation
                            if (!cancel.Token.IsCancellationRequested) // check cancel token periodically
                                o.OnNext(i++);
                            else
                            {
                                Console.WriteLine("Aborting because cancel event was signaled!");
                                o.OnCompleted();
                                return;
                            }
                        }
                    }
                        );

                    return cancel;
                }
                    );

            IDisposable subscription = ob.Subscribe(i => Console.WriteLine(i));
            Console.WriteLine("Press any key to cancel");
            Console.ReadKey();
            subscription.Dispose();
            Console.WriteLine("Press any key to quit");
            Console.ReadKey(); // give background thread chance to write the cancel acknowledge message
        }
コード例 #4
0
        IObservable<Unit> SaveThumbnailToFile (FileRequest request)
        {
            return Observable.Create<Unit> (o => {
                var description = request.DescriptionAs<AssetDescription> ();
                var disp = new CancellationDisposable ();
                var token = disp.Token;

                GetAsset (description, token).ContinueWith (t => {
                    var saveUrl = NSUrl.FromFilename (request.Filename);
                    
                    using (var asset = t.Result)
                    using (var representation = asset.DefaultRepresentation)
                    using (var thumbnail = new UIImage (asset.Thumbnail))
                    using (var destination = CGImageDestination.FromUrl (saveUrl, representation.Uti, 1))
                    using (var cgImage = thumbnail.CGImage) {
                        destination.AddImage (cgImage, new NSMutableDictionary {
                            { CGImageProperties.Orientation, NSNumber.FromInt32 (ImageHelper.ToExifOrientation (thumbnail.Orientation)) }
                        });
                        
                        destination.Close ();
                    }
                    
                    o.OnCompleted ();
                }, token).RouteExceptions (o);
                
                return disp;
            });
        }
コード例 #5
0
        public static void ShowAddPackageDialog(string selectedFileName, string projectGuid = null)
        {
            Paket.Dependencies dependenciesFile = null;

            try
            {
                dependenciesFile = Paket.Dependencies.Locate(selectedFileName);
            }
            catch (Exception)
            {
                var dir = new System.IO.FileInfo(SolutionExplorerExtensions.GetSolutionFileName()).Directory.FullName;
                Dependencies.Init(dir);
                dependenciesFile = Paket.Dependencies.Locate(selectedFileName);
            }

            var secondWindow = new AddPackage();

            //Create observable paket trace
            var paketTraceObs = Observable.Create<Logging.Trace>(observer =>
            {
                [email protected](x => observer.OnNext(x));
                return Disposable.Create(() =>
                {
                   
                });
               
            });

            Action<NugetResult> addPackageToDependencies = result =>
            {
                if (projectGuid != null)
                {
                    var guid = Guid.Parse(projectGuid);
                    SolutionExplorerExtensions.UnloadProject(guid);
                    dependenciesFile.AddToProject(Microsoft.FSharp.Core.FSharpOption<string>.None, result.PackageName, "", false, false, false, false, selectedFileName, true, SemVerUpdateMode.NoRestriction);
                    SolutionExplorerExtensions.ReloadProject(guid);
                }
                else
                    dependenciesFile.Add(Microsoft.FSharp.Core.FSharpOption<string>.None, result.PackageName, "", false, false, false, false, false, true, SemVerUpdateMode.NoRestriction);
            };

            Func<string, IObservable<string>> searchNuGet = 
                searchText => Observable.Create<string>(obs =>
                {
                    var disposable = new CancellationDisposable();

                    dependenciesFile
                        .SearchPackagesByName(
                            searchText,
                            FSharpOption<CancellationToken>.Some(disposable.Token),
                            FSharpOption<int>.None)
                        .Subscribe(obs);

                    return disposable;
                });
          
            //TODO: Use interfaces?
            secondWindow.ViewModel = new AddPackageViewModel(searchNuGet, addPackageToDependencies, paketTraceObs);
            secondWindow.ShowDialog();
        }
コード例 #6
0
ファイル: WebSocketLab.cs プロジェクト: ibebbs/Rxx
    protected override void Main()
    {
      if (Environment.OSVersion.Version < new Version(6, 2))
      {
        TraceError(Text.LabRequiresWindows8OrHigher);
        return;
      }

      const int port = 5494;
      string subProtocol = GetType().Name;

      var userMessages = new BehaviorSubject<string>(null);

      var client = new ClientWebSocket();

      client.Options.AddSubProtocol(subProtocol);

      using (client)
      using (var cancel = new CancellationDisposable())
      using (ObservableHttpListener
        .StartWebSockets(new IPEndPoint(IPAddress.Loopback, port), subProtocol)
        .Subscribe(
          async request =>
          {
            using (var socket = request.WebSocket)
            {
              try
              {
                var message = await ReceiveMessageAsync(socket, cancel.Token);
                await SendMessageAsync("You sent \"" + message + "\"", socket, cancel.Token);
                await ReceiveCloseMessageAsync(socket, cancel.Token);
              }
              catch (OperationCanceledException)
              {
              }
            }
          },
          TraceError))
      using ((from _ in client.ConnectAsync(new Uri("ws://localhost:" + port), cancel.Token).ToObservable()
                .Do(_ => TraceLine(Environment.NewLine + "(Connected to host on sub-protocol \"{0}\")", client.SubProtocol))
              from message in userMessages.Where(m => m != null).Take(1)
              from __ in SendMessageAsync(message, client, cancel.Token).ToObservable()
              from response in ReceiveMessageAsync(client, cancel.Token).ToObservable()
                .Do(___ => client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done", cancel.Token))
              select response)
              .Subscribe(
                response => TraceLine("Response: {0}", response),
                TraceError,
                () => TraceLine("{0}: {1}", Text.Client, Text.Done)))
      {
        userMessages.OnNext(UserInput("{0}> ", Instructions.EnterAMessage));

        TraceStatus(Instructions.PressAnyKeyToCancel);

        WaitForKey();
      }
    }
コード例 #7
0
        /// <summary>
        /// Instantiates the <see cref="ProgressDialog"/>.
        /// </summary>
        /// <param name="title">The title.</param>
        /// <param name="message">The message.</param>
        public ProgressDialog(string title, string message)
        {
            InitializeComponent();

            Heading = title;
            Message = message;

            _cancellationDisposable = new CancellationDisposable();
        }
        public override long RunPass()
        {
            var ob = Observable.Create<long>(o =>
             {
                 var cancel = new CancellationDisposable(); // internally creates a new CancellationTokenSource
                 Scheduler.Default.Schedule(() =>
                 {
                     for (long i = 0; i < Iterations; i++)
                     {
                         //Thread.Sleep(200);  // here we do the long lasting background operation
                         if (!cancel.Token.IsCancellationRequested)    // check cancel token periodically
                             o.OnNext(i++);
                         else
                         {
                             Console.WriteLine("Aborting because cancel event was signaled!");
                             o.OnCompleted();
                             return;
                         }
                     }
                 }
                 );

                 return cancel;
             }
             );

            _disruptor.Start();

            var sw = Stopwatch.StartNew();
            var subscription = ob.Subscribe(i =>
            {
                
                var sequence = _ringBuffer.Next();
                _ringBuffer[sequence].Value = i;
                _ringBuffer.Publish(sequence);
            });
            //这里取消任务
            //subscription.Dispose();
            //for (long i = 0; i < Iterations; i++)
            //{
            //    var sequence = _ringBuffer.Next();
            //    _ringBuffer[sequence].Value = i;
            //    _ringBuffer.Publish(sequence);
            //}

            _mru.WaitOne();

            var opsPerSecond = (Iterations * 1000L) / sw.ElapsedMilliseconds;
            _disruptor.Shutdown();

            Assert.AreEqual(ExpectedResult, _fizzBuzzEventHandler.FizzBuzzCounter);

            return opsPerSecond;
        }
コード例 #9
0
        public IObservable<Unit> Fetch (Request request)
        {
            return Observable.Create<Unit> (o => {
                var client = new DBRestClient (DBSession.SharedSession);
                var cancel = new CancellationDisposable ();

                var fileRequest = request as FileRequest;
                if (fileRequest == null)
                    throw new NotImplementedException ("DropboxSource only supports saving images to disk");

                var subscription = StartDropboxTask (client, fileRequest, cancel.Token)
                    .ToObservable ()
                    .Subscribe (o);

                return new CompositeDisposable (client, cancel, subscription);
            });
        }
コード例 #10
0
        private bool BaseExecute(CancellationDisposable cancellation)
        {
            //start timer
            if (WatchDog != null)
            {
                WatchDog.Enabled = true;
                WatchDog.Start();
            }

            bool success = Execute(cancellation);

            if (WatchDog != null)
            {
                WatchDog.Enabled = false;
                WatchDog.Stop();
            }

            return success;
        }
コード例 #11
0
 protected abstract bool Execute(CancellationDisposable cancellation);
コード例 #12
0
        protected override bool Execute(CancellationDisposable cancellation)
        {
            TraceMessage("Execute");

            Thread.Sleep(3000);
            return true;
        }
コード例 #13
0
 public MessageToken()
 {
     Cancellation = new CancellationDisposable();
     InErrorState = new BooleanDisposable();
 }
コード例 #14
0
        private CancellationDisposable QueueMechanism(IObserver<QueueStates> observer)
        {
            var cancellation = new CancellationDisposable();
            // internally creates a new CancellationTokenSource

            NewThreadScheduler.Default.Schedule((t) =>
                                                    {
                                                        QueueStates state = QueueStates.StartUp;
                                                        for (; ; )
                                                        {
                                                            bool success = ExecuteStateLogic(state, cancellation);

                                                            if (cancellation.Token.IsCancellationRequested)
                                                            {
                                                                state = state == QueueStates.Teardown
                                                                            ? GetNextState(state)
                                                                            : QueueStates.Teardown;
                                                            }

                                                            else if (success)
                                                                state = GetNextState(state);
                                                            else
                                                                state = QueueStates.Error;

                                                            if (state == QueueStates.WaitingForTrigger)
                                                            {
                                                            }
                                                            else if (state != QueueStates.Stopped)
                                                                observer.OnNext(state);
                                                            else
                                                            {
                                                                TraceMessage("--**-- Stopped --**--");
                                                                observer.OnCompleted();
                                                                return;
                                                            }

                                                            //// here we do the long lasting background operation
                                                            //if (!cancellation.Token.IsCancellationRequested)
                                                            //{
                                                            //    // check cancel token periodically

                                                            //}
                                                            //else
                                                            //{
                                                            //    TraceMessage("Aborting because cancel event was signaled!");
                                                            //    observer.OnCompleted();
                                                            //    return;
                                                            //}
                                                        }
                                                    }
                );

            return cancellation;
        }
コード例 #15
0
        private bool ExecuteStateLogic(QueueStates state, CancellationDisposable cancellation)
        {
            switch (state)
            {
                case QueueStates.StartUp:
                    return true;

                case QueueStates.Initializing:
                    return Initialize();

                case QueueStates.WaitingForTrigger:
                    return true;

                case QueueStates.Executing:
                    return BaseExecute(cancellation);

                case QueueStates.Teardown:
                    return Teardown();

                case QueueStates.Stopped:
                    // not used
                    return true;

                case QueueStates.Error:
                    OnError("-- illogical flow --");
                    return true;

                default:
                    return false;
            }
        }
コード例 #16
0
        IObservable<Unit> SaveFullResolutionImageToMemory (MemoryRequest request)
        {
            return Observable.Create<Unit> (o => {
                var description = request.DescriptionAs<AssetDescription> ();
                var disp = new CancellationDisposable ();
                var token = disp.Token;

                GetAsset (description, token).ContinueWith (t => {
                    using (var asset = t.Result)
                    using (var representation = asset.DefaultRepresentation)
                        request.Image = new UIImage (representation.GetImage ());

                    o.OnCompleted ();
                }, token).RouteExceptions (o);

                return disp;
            });
        }
コード例 #17
0
        private async Task ExecuteAsync(object current, Func<CancellationToken, Task> action, CancellationToken token)
        {
            // Create a task completion source.
            var doneTaskSource = new TaskCompletionSource<bool>();

            // Set the "current task".
            var doneTask = doneTaskSource.Task;

            // Local variables for the switch state.
            var active = default(object);
            var currentTask = default(Task);
            var cancelSwitch = default(CancellationDisposable);

            // Enter the lock and update the switch state.
            lock (_gate)
            {
                // If nothing is active, the current call becomes active.
                if (_active == null)
                {
                    _active = active = current;
                    currentTask = _currentTask = doneTask;
                    _serialDisposable.Disposable = cancelSwitch = _cancelSwitch = new CancellationDisposable();
                }
                // If the current call is the active kind, repeat and add a continuation.
                else if (_active == current)
                {
                    active = _active;
                    cancelSwitch = _cancelSwitch;
                    currentTask = _currentTask = doneTask = _currentTask.ContinueWith(_ => doneTaskSource.Task).Unwrap();
                }
                // Otherwise, set the local variables for awaiting.
                else
                {
                    active = _active;
                    currentTask = _currentTask;
                    cancelSwitch = _cancelSwitch;
                }
            }

            // If the current task is not active, cancel the active task and try again. 
            if (active != current)
            {
                cancelSwitch.Dispose();
                await currentTask;
                await ExecuteAsync(current, action, token);
            }
            // Else, run the current task.
            else
            {
                using (var localCancellationSource = new CancellationDisposable())
                using (cancelSwitch.Token.Register(localCancellationSource.Dispose))
                using (token.Register(localCancellationSource.Dispose))
                {
                    try
                    {
                        await action(localCancellationSource.Token);
                    }
                    catch (OperationCanceledException ex)
                    {
                        if (ex.CancellationToken != localCancellationSource.Token)
                        {
                            throw;
                        }

                        token.ThrowIfCancellationRequested();

                        if (_serialDisposable.IsDisposed)
                        {
                            throw new ObjectDisposedException("SwitchBlock");
                        }
                    }
                    finally
                    {
                        lock (_gate)
                        {
                            // If the current task is the final task, reset the active task.
                            if (_currentTask == doneTask)
                            {
                                _active = null;
                            }
                        }

                        doneTaskSource.SetResult(true);
                    }
                }
            }
        }
コード例 #18
0
        /// <summary>
        /// same as the previous "TestBoolDisposable", but the message that "production completes" NEVRE shows
        /// so it is much more clear that it is the Take operator notify the observer to complete 
        /// NOT the original source
        /// </summary>
        private static void TestCancelDisposable(int total, int expected)
        {
            IObservable<int> source = Observable.Create<int>(observer =>
            {
                CancellationDisposable disposable = new CancellationDisposable();

                Task.Factory.StartNew(() =>
                                          {
                                              for (int index = 0; index < total; index++)
                                              {
                                                  disposable.Token.ThrowIfCancellationRequested();
                                                  observer.Consume(index);
                                              }

                                              observer.OnCompleted();
                                              Console.WriteLine("[ NEVER DISPLAYED ] production completes.");
                                          }, disposable.Token);

                return disposable;
            });

            source.ConsumeSome(expected);
            Helper.Pause();
        }
コード例 #19
0
        /// <summary>
        /// Create With Disposable & Scheduler - Canceling an asynchronous operation
        /// </summary>
        public static void DisposableScheduler()
        {
            IObservable<int> ob =
                Observable.Create<int>(o =>
                {
                    var cancel = new CancellationDisposable();
                    NewThreadScheduler.Default.Schedule(() =>
                    {
                        int i = 0;
                        while (!cancel.Token.IsCancellationRequested)
                        {
                            Thread.Sleep(200);
                            o.OnNext(i++);
                        }

                        Console.WriteLine("Aborting because cancel evente was signled.");
                        o.OnCompleted();
                    });
                    return cancel;
                });

            IDisposable subscription = ob.Subscribe(i => Console.WriteLine("\t{0:000}",i));
            Console.WriteLine("Press any key to cancel");
            Console.ReadKey();
            subscription.Dispose();
            Console.WriteLine("Background should be cleaned up by now, Press any key to quit");
            Console.ReadKey(); // give background thread chance to write cancel message
        }
コード例 #20
0
ファイル: MimeMessageLoader.cs プロジェクト: Jaben/Papercut
        public IObservable<MimeMessage> Get(MessageEntry messageEntry)
        {
            _logger.Verbose("Loading Message Entry {@MessageEntry}", messageEntry);

            return Observable.Create<MimeMessage>(
                o =>
                {
                    // in case of multiple subscriptions...
                    var observer = Observer.Synchronize(o, true);
                    var disposable = new CancellationDisposable();

                    MimeMessage message = null;

                    try
                    {
                         message = MimeMessageCache.GetOrSet(
                            messageEntry.File,
                            () =>
                            {
                                _logger.Verbose(
                                    "Getting Message Data from Cached Message Repository",
                                    messageEntry);
                                var messageData = _messageRepository.GetMessage(messageEntry);
                                MimeMessage mimeMessage;

                                // wrap in a memorystream...
                                using (var ms = new MemoryStream(messageData))
                                {
                                    _logger.Verbose(
                                        "MimeMessage Load for {@MessageEntry}",
                                        messageEntry);

                                    mimeMessage = MimeMessage.Load(
                                        ParserOptions.Default,
                                        ms,
                                        disposable.Token);
                                }

                                return mimeMessage;
                            },
                            m =>
                            {
                                var policy = new CacheItemPolicy
                                {
                                    SlidingExpiration = TimeSpan.FromSeconds(10)
                                };

                                MimeMessageCache.Add(messageEntry.File, m, policy);
                            });
                    }
                    catch (OperationCanceledException)
                    {
                        // no need to respond...
                    }
                    catch (Exception ex)
                    {
                        _logger.Error(ex, "Exception Loading {@MessageEntry}", messageEntry);
                        observer.OnError(ex);
                    }

                    if (message != null)
                    {
                        observer.OnNext(message);
                        observer.OnCompleted();
                    }

                    return disposable;
                }).SubscribeOn(TaskPoolScheduler.Default);
        }
コード例 #21
0
        IObservable<Unit> SaveThumbnailToMemory (MemoryRequest request)
        {
            return Observable.Create<Unit> (o => {
                var description = request.DescriptionAs<AssetDescription> ();
                var disp = new CancellationDisposable ();
                var token = disp.Token;

                GetAsset (description, token).ContinueWith (t => {
                    using (var asset = t.Result)
                        request.Image = new UIImage (asset.Thumbnail);

                    o.OnCompleted ();
                }, token).RouteExceptions (o);

                return disp;
            });
        }
コード例 #22
0
ファイル: DisposableTests.cs プロジェクト: Ziriax/Rx.NET
 public void CancellationDisposable_DefaultCtor()
 {
     var c = new CancellationDisposable();
     Assert.IsNotNull(c.Token);
     Assert.IsFalse(c.Token.IsCancellationRequested);
     Assert.IsTrue(c.Token.CanBeCanceled);
     c.Dispose();
     Assert.IsTrue(c.IsDisposed);
     Assert.IsTrue(c.Token.IsCancellationRequested);
 }
        protected override long RunDisruptorPass()
        {
            var ob = Observable.Create<long>(o =>
            {
                var cancel = new CancellationDisposable(); // internally creates a new CancellationTokenSource
               
                Scheduler.Default.Schedule(() =>
                {
                    for (long i = 0; i < ITERATIONS; i++)
                    {
                        //Thread.Sleep(200);  // here we do the long lasting background operation
                        if (!cancel.Token.IsCancellationRequested)    // check cancel token periodically
                            o.OnNext(i++);
                        else
                        {
                            Console.WriteLine("Aborting because cancel event was signaled!");
                            o.OnCompleted();
                            return;
                        }
                    }
                }
                );

                return cancel;
            }
             );

            var spinwait = default(SpinWait);
            //var latch = new CountdownEvent(1);
            var latch = new ManualResetEvent(false);
            var expectedCount = myRunnable.GetSequence.Value + ITERATIONS;
            myRunnable.Reset(latch, expectedCount);
            var _scheduler = new RoundRobinThreadAffinedTaskScheduler(4);
            //TaskScheduler.Default调度器 CPU 约在 50 % 两个繁忙,两个空闲
            //
           
            Task.Factory.StartNew(myRunnable.Run, CancellationToken.None, TaskCreationOptions.None,TestTaskScheduler);

            var start = Stopwatch.StartNew();

            var sequencer = this.sequencer;
            //var range = Observable.Range(0, 1000 * 1000 * 100, Scheduler.Default)
            //       .Subscribe(i => {
            //           long next = sequencer.Next();
            //           sequencer.Publish(next);
            //       });
           // var subscription = ob.Subscribe(i =>
            for (long i = 0; i < ITERATIONS; i++)
            {
                long next = sequencer.Next();
                sequencer.Publish(next);
            }
           //);

            latch.WaitOne();
            long opsPerSecond = (ITERATIONS * 1000L) / start.ElapsedMilliseconds;

            WaitForEventProcessorSequence(expectedCount, spinwait,myRunnable);

            return opsPerSecond;
        }
コード例 #24
0
ファイル: DisposableTests.cs プロジェクト: Ziriax/Rx.NET
 public void CancellationDisposable_TokenCtor()
 {
     var t = new CancellationTokenSource();
     var c = new CancellationDisposable(t);
     Assert.IsTrue(t.Token == c.Token);
     Assert.IsFalse(c.Token.IsCancellationRequested);
     Assert.IsTrue(c.Token.CanBeCanceled);
     c.Dispose();
     Assert.IsTrue(c.IsDisposed);
     Assert.IsTrue(c.Token.IsCancellationRequested);
 }
コード例 #25
0
        IObservable<Unit> SaveFullResolutionImageToFile (FileRequest request)
        {
            return Observable.Create<Unit> (o => {
                var description = request.DescriptionAs<AssetDescription> ();
                var disp = new CancellationDisposable ();
                var token = disp.Token;

                GetAsset (description, token).ContinueWith (t => {
                    using (File.Create (request.Filename))
                    using (var asset = t.Result)
                    using (var representation = asset.DefaultRepresentation) 
                    using (var stream = new NSOutputStream (request.Filename, true)) {
                        stream.Open ();

                        long offset = 0;
                        uint bytesRead = 0;

                        NSError err;

                        // A large enough buffer that shouldn't cause memory warnings
                        byte [] buffer = new byte [131072];

                        GCHandle handle = GCHandle.Alloc (buffer, GCHandleType.Pinned);
                        IntPtr pointer = handle.AddrOfPinnedObject ();
                        
                        unsafe {
                            while (offset < representation.Size && stream.HasSpaceAvailable ()) {
                                bytesRead = representation.GetBytes (pointer, offset, (uint)buffer.Length, out err);
                                stream.Write (buffer, bytesRead);
                                offset += bytesRead;
                            }
                        }
                        
                        stream.Close ();
                        handle.Free ();
                    }

                    o.OnCompleted ();
                }, token).RouteExceptions (o);

                return disp;
            });
        }