/// <summary> /// Initializes a new instance of the <see cref="GroupController"/> class. /// </summary> public GroupController() { _cleanUp = Disposable.Create(() => _regroupSubject.OnCompleted()); }
public void UsingAsync_CancelFactory() { var N = 10;// 0000; for (var i = 0; i < N; i++) { var gate = new object(); var disposed = false; var called = false; var s = new ManualResetEvent(false); var e = new ManualResetEvent(false); var x = new ManualResetEvent(false); var xs = Observable.Using( ct => Task.Factory.StartNew(() => Disposable.Create(() => { lock (gate) { disposed = true; } }) ), (_, ct) => Task.Factory.StartNew(() => { s.Set(); e.WaitOne(); while (!ct.IsCancellationRequested) { ; } x.Set(); return(Observable.Defer(() => { called = true; return Observable.Return(42); })); }) ); var d = xs.Subscribe(_ => { }); s.WaitOne(); // // This will *eventually* set the CancellationToken. There's a fundamental race between observing the CancellationToken // and returning the IDisposable that will set the CancellationTokenSource. Notice this is reflected in the code above, // by looping until the CancellationToken is set. // d.Dispose(); e.Set(); x.WaitOne(); while (true) { lock (gate) { if (disposed) { break; } } } Assert.False(called, i.ToString()); } }
public static IDisposable RegisterHover(this View view, EventHandler <View.HoverEventArgs> handler) { view.Hover += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.Hover -= handler))); }
public IDisposable Subscribe(IObserver <TProduct> observer) { ConsumerObserver = observer; return(Disposable.Create(() => ConsumerObserver = null)); }
public IObservable <IGroupChangeSet <TObject, TKey, TGroupKey> > Run() { return(Observable.Create <IGroupChangeSet <TObject, TKey, TGroupKey> > ( observer => { var locker = new object(); //create source group cache var sourceGroups = _source.Synchronize(locker) .Group(_groupSelector) .DisposeMany() .AsObservableCache(); //create parent groups var parentGroups = _resultGroupSource.Synchronize(locker) .Transform(x => { //if child already has data, populate it. var result = new ManagedGroup <TObject, TKey, TGroupKey>(x); var child = sourceGroups.Lookup(x); if (child.HasValue) { //dodgy cast but fine as a groups is always a ManagedGroup; var group = (ManagedGroup <TObject, TKey, TGroupKey>)child.Value; result.Update(updater => updater.Update(group.GetInitialUpdates())); } return result; }) .DisposeMany() .AsObservableCache(); //connect to each individual item and update the resulting group var updateFromcChilds = sourceGroups.Connect() .SubscribeMany(x => x.Cache.Connect().Subscribe(updates => { var groupToUpdate = parentGroups.Lookup(x.Key); if (groupToUpdate.HasValue) { groupToUpdate.Value.Update(updater => updater.Update(updates)); } })) .DisposeMany() .Subscribe(); var notifier = parentGroups .Connect() .Select(x => { var groups = x.Select(s => new Change <IGroup <TObject, TKey, TGroupKey>, TGroupKey>(s.Reason, s.Key, s.Current)); return new GroupChangeSet <TObject, TKey, TGroupKey>(groups); }) .SubscribeSafe(observer); return Disposable.Create(() => { notifier.Dispose(); sourceGroups.Dispose(); parentGroups.Dispose(); updateFromcChilds.Dispose(); }); })); }
public static IDisposable RegisterLayoutChange(this View view, EventHandler <View.LayoutChangeEventArgs> handler) { view.LayoutChange += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.LayoutChange -= handler))); }
private void ProcessSubscription(string subscriptionId, IMessage message, RequestStreamHandler <TRequest, TUpdate> requestStreamHandler) { // In order to prevent races/resource-leaks here we must: // * Monitor session diconnections before attempting to create a request context. // - Otherwise, a session could be destroyed and we would never clean up its resources, as we'd // miss the notification. // * Create the subscription to monitor sessions and add update our state all within a single // critical region. In addition to this, we must ensure session destruction callbacks are // fired on a different thread. // - Otherwise, we may attempt to remove the session's resources before they are added. var sessionId = message.SessionId; var replyDestination = message.ReplyTo; var subscription = new CompositeDisposable(); TRequest request; if (!TryDeserializeRequest(subscriptionId, message, out request)) { return; } var clientId = message.Properties.GetString(OperationKeys.ClientId); if (clientId == null) { Log.Warning("No ClientId found. Ignoring."); return; } var sessionDestroyedHandler = new AnonymousUserSessionHandler(_ => { }, _ => { lock (_subscriptions) { // TODO: Make the Java version clean all resources hooked up here. // ReSharper disable once AccessToDisposedClosure subscription.Dispose(); _subscriptions.Remove(subscriptionId); } }); lock (_subscriptions) { // TODO: How do we clean up when IsSessionRequired == false? if (IsSessionRequired) { subscription.Add(UserSessionCache.Subscribe(sessionId, sessionDestroyedHandler)); } var context = CreateRequestContext(message); if (context == null) { Log.Warning("Failed to create request context. Ignoring."); subscription.Dispose(); // Don't listen for session destruction if it doesn't exist. return; } // At this point we know the session exists or existed and we know it will be cleared up (after we // exit the critical region) by the sessionResourceCleaner if it is destroyed. _subscriptions.Add(subscriptionId, subscription); try { const int notFinished = 0; const int finished = 1; var subscriptionState = notFinished; var notificationSubscription = requestStreamHandler(context, request, new AnonymousStreamHandler <TUpdate>( // TODO: I remove the session from the lookup AND ALSO dipose subscription here. // This is analagous to the AutoDetachObserver<T> in Rx. Should we do the same in the Java version? // Review with John. -ZB update => OnUpdated(subscriptionId, replyDestination, update), error => { if (Interlocked.Exchange(ref subscriptionState, finished) == notFinished) { OnFailed(subscriptionId, replyDestination, error); } }, () => { if (Interlocked.Exchange(ref subscriptionState, finished) == notFinished) { OnCompleted(subscriptionId, replyDestination); } })); subscription.Add(Disposable.Create(() => { var hasAlreadyFinished = Interlocked.Exchange(ref subscriptionState, finished) == finished; if (!hasAlreadyFinished) { notificationSubscription.Dispose(); } })); } catch (Exception e) { const string error = "Failed to process request"; OnFailed(subscriptionId, replyDestination, new MessagingException(error, e)); Log.Error(error, e); } } SendAck(subscriptionId, replyDestination, clientId); }
public LogEntryViewer(ILogEntryService logEntryService) { //build an observable filter var filter = this.WhenAnyValue(x => x.SearchText) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(BuildFilter); //filter, sort and populate reactive list. var loader = logEntryService.Items.Connect() .Transform(le => new LogEntryProxy(le)) .DelayRemove(TimeSpan.FromSeconds(0.75), proxy => proxy.FlagForRemove()) .Filter(filter) .Sort(SortExpressionComparer <LogEntryProxy> .Descending(le => le.TimeStamp).ThenByDescending(l => l.Key), SortOptions.UseBinarySearch) .ObserveOn(RxApp.MainThreadScheduler) .Bind(Data) .DisposeMany() .Subscribe(); //aggregate total items var summariser = logEntryService.Items.Connect() .QueryWhenChanged(items => { var debug = items.Count(le => le.Level == LogLevel.Debug); var info = items.Count(le => le.Level == LogLevel.Info); var warn = items.Count(le => le.Level == LogLevel.Warning); var error = items.Count(le => le.Level == LogLevel.Error); return(new LogEntrySummary(debug, info, warn, error)); }) .Subscribe(s => Summary = s); //manage user selection, delete items command var selectedItems = _selectionController.SelectedItems.Connect().Publish(); //Build a message from selected items _deleteItemsText = selectedItems.QueryWhenChanged(query => { if (query.Count == 0) { return("Select log entries to delete"); } if (query.Count == 1) { return("Delete selected log entry?"); } return($"Delete {query.Count} log entries?"); }) .ToProperty(this, viewmodel => viewmodel.DeleteItemsText, "Select log entries to delete"); //make a command out of selected items - enabling the command when there is a selection DeleteCommand = ReactiveCommand.Create(() => { var toRemove = _selectionController.SelectedItems.Items.Select(proxy => proxy.Original).ToArray(); _selectionController.Clear(); logEntryService.Remove(toRemove); }, selectedItems.QueryWhenChanged(query => query.Count > 0)); var connected = selectedItems.Connect(); _cleanUp = Disposable.Create(() => { loader.Dispose(); connected.Dispose(); _deleteItemsText.Dispose(); DeleteCommand.Dispose(); _selectionController.Dispose(); summariser.Dispose(); }); }
private IConnectableObservable <byte[]> CreateObserver(WebSocket webSocket) { return(Observable.Create <byte[]>(async(observer, cancellation) => { try { while (webSocket.IsConnected && !cancellation.IsCancellationRequested) { WebSocketMessageReadStream message = await webSocket.ReadMessageAsync(cancellation) .ConfigureAwait(false); if (message == null) { continue; } switch (message.MessageType) { case WebSocketMessageType.Text: string messageContent; using (StreamReader streamReader = new StreamReader(message, Encoding.UTF8)) { messageContent = await streamReader.ReadToEndAsync(); } WebCastMessage webCastMessage = messageContent.FromJson <WebCastMessage>(); switch (webCastMessage.Type) { case "metadata": _logger.Debug("Metadata received: {webCastMessage.Data}"); break; default: _logger.Warning("Invalid message"); break; } break; case WebSocketMessageType.Binary: byte[] bytes = message.ReadFully(); observer.OnNext(bytes); break; } } observer.OnCompleted(); } catch (Exception exception) { _logger.Error(exception, "Error Handling connection"); observer.OnError(exception); } return Disposable.Create(webSocket.Dispose); }) .Publish()); }
public static async Task <IDisposable> UseWaitAsync(this SemaphoreSlim semaphore) { await semaphore.WaitAsync(); return(Disposable.Create(() => semaphore.Release())); }
/* ----------------------------------------------------------------- */ /// /// SubscribeAsync /// /// <summary> /// データ受信時に非同期で実行する処理を登録します。 /// </summary> /// /* ----------------------------------------------------------------- */ public IDisposable SubscribeAsync(Func <TimeSpan, Task> action) { Subscriptions.Add(action); return(Disposable.Create(() => Subscriptions.Remove(action))); }
private static void Impl(bool primaryFirst, bool primaryRandom, IEnumerable <int> nDependents) { var rand = new Random(); foreach (var n in nDependents) { var e = new ManualResetEvent(false); var hasDependent = new ManualResetEvent(false); var r = new RefCountDisposable(Disposable.Create(() => { e.Set(); })); var d = default(IDisposable); if (primaryFirst) { d = r.GetDisposable(); r.Dispose(); } else if (primaryRandom) { var sleep = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0; ThreadPool.QueueUserWorkItem(_ => { hasDependent.WaitOne(); Helpers.SleepOrSpin(sleep); r.Dispose(); }); if (n == 0) { hasDependent.Set(); } } Console.Write(n + " - "); var cd = new CountdownEvent(n * 2); for (int i = 0; i < n; i++) { var j = i; var sleep1 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0; var sleep2 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0; var sleep3 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0; ThreadPool.QueueUserWorkItem(_ => { Helpers.SleepOrSpin(sleep1); Console.Write("+"); var f = r.GetDisposable(); if (j == 0) { hasDependent.Set(); } Helpers.SleepOrSpin(sleep2); ThreadPool.QueueUserWorkItem(__ => { Helpers.SleepOrSpin(sleep3); f.Dispose(); Console.Write("-"); cd.Signal(); }); cd.Signal(); }); } cd.Wait(); if (primaryFirst) { d.Dispose(); } else if (!primaryRandom) { r.Dispose(); } e.WaitOne(); Console.WriteLine("."); } }
public IDisposable StartPeriodicTimer(Action action, TimeSpan period) { _action = action; _period = period; return(Disposable.Create(() => _action = null)); }
// For requests that do not use requestId. // Single result(end=null): CurrentTime, ScannerParameters // Multiple results (end=false=>true): AccountPositions, OpenOrders // Continuous results (end=false): AccountUpdate, NewsBulletins // End type: not type T internal static IObservable <T> ToObservable <T>( this IObservable <object> source, Action subscribe, Action unsubscribe = null, Func <object, bool> end = null) where T : class { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (subscribe == null) { throw new ArgumentNullException(nameof(subscribe)); } return(Observable.Create <T>(observer => { bool?cancelable = null; var subscription = source .Finally(() => cancelable = false) .Subscribe( onNext: m => { var theEnd = end != null && end(m); if (m is T t && (end == null || !theEnd)) { observer.OnNext(t); } if (end == null || theEnd) { cancelable = false; observer.OnCompleted(); } }, onError: observer.OnError, onCompleted: observer.OnCompleted); if (cancelable == null) { subscribe(); } if (cancelable == null) { cancelable = true; } return Disposable.Create(() => { if (cancelable == true) { try { unsubscribe?.Invoke(); } catch (Exception e) { // ignored Debug.WriteLine("Unexpected: " + e.ToString()); } } subscription.Dispose(); }); }));
private IDisposable StartObserving(Task task) { task.ContinueWith(ContinueObservedTask, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); return(Disposable.Create(() => UnobserveTaskFailure(task))); }
/// <summary> /// When this method is called, an object will not fire change /// notifications (neither traditional nor Observable notifications) /// until the return value is disposed. /// </summary> /// <returns>An object that, when disposed, reenables change /// notifications.</returns> public IDisposable SuppressChangeNotifications() { Interlocked.Increment(ref changeNotificationsSuppressed); return(Disposable.Create(() => Interlocked.Decrement(ref changeNotificationsSuppressed))); }
/// <summary> /// Create an observable for the specified window or HwndSource /// </summary> /// <param name="window">Window</param> /// <param name="hWndSource">HwndSource</param> /// <returns>IObservable</returns> private static IObservable <WindowMessageInfo> WinProcMessages(Window window, HwndSource hWndSource) { if (window == null && hWndSource == null) { throw new NotSupportedException("One of Window or HwndSource must be supplied"); } if (window != null && hWndSource != null) { throw new NotSupportedException("Either Window or HwndSource must be supplied"); } return(Observable.Create <WindowMessageInfo>(observer => { // This handles the message, and generates the observable OnNext IntPtr WindowMessageHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { observer.OnNext(WindowMessageInfo.Create(hwnd, msg, wParam, lParam)); // ReSharper disable once AccessToDisposedClosure if (hWndSource.IsDisposed) { observer.OnCompleted(); } return IntPtr.Zero; } void HwndSourceDisposedHandle(object sender, EventArgs e) { observer.OnCompleted(); } void RegisterHwndSource() { hWndSource.Disposed += HwndSourceDisposedHandle; hWndSource.AddHook(WindowMessageHandler); } if (window != null) { hWndSource = window.ToHwndSource(); } if (hWndSource != null) { RegisterHwndSource(); } else { // No, try to get it later window.SourceInitialized += (sender, args) => { hWndSource = window.ToHwndSource(); RegisterHwndSource(); // Simulate the WM_NCCREATE observer.OnNext(WindowMessageInfo.Create(hWndSource.Handle, (int)WindowsMessages.WM_NCCREATE, IntPtr.Zero, IntPtr.Zero)); }; } return Disposable.Create(() => { hWndSource.Disposed -= HwndSourceDisposedHandle; hWndSource.RemoveHook(WindowMessageHandler); hWndSource.Dispose(); }); }) // Make sure there is always a value produced when connecting .Publish() .RefCount()); }
public static IDisposable RegisterContextMenuCreated(this View view, EventHandler <View.CreateContextMenuEventArgs> handler) { view.ContextMenuCreated += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.ContextMenuCreated -= handler))); }
public IDisposable Subscribe(IObserver <int> observer) { _subscribeCount++; _observer = observer; return(Disposable.Create(() => { _disposed = true; })); }
public static IDisposable RegisterLongClick(this View view, EventHandler <View.LongClickEventArgs> handler) { view.LongClick += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.LongClick -= handler))); }
/* ----------------------------------------------------------------- */ /// /// Subscribe /// /// <summary> /// SendCallback で実行される処理を登録します。 /// </summary> /// /// <param name="action">処理を表すオブジェクト</param> /// /// <returns>登録解除用オブジェクト</returns> /// /* ----------------------------------------------------------------- */ public IDisposable Subscribe(Action <T> action) { _subscriptions.Add(action); return(Disposable.Create(() => _subscriptions.Remove(action))); }
public static IDisposable RegisterKeyPress(this View view, EventHandler <View.KeyEventArgs> handler) { view.KeyPress += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.KeyPress -= handler))); }
protected override void OnEnable() { base.OnEnable(); xpcfComponentManager = xpcf_api.getComponentManagerInstance(); Disposable.Create(xpcfComponentManager.clear).AddTo(subscriptions); xpcfComponentManager.AddTo(subscriptions); #if !UN conf.path = File.ReadAllText("confPath.txt"); #endif if (xpcfComponentManager.load(conf.path) != XPCFErrorCode._SUCCESS) { Debug.LogErrorFormat("Failed to load the configuration file {0}", conf.path); enabled = false; return; } switch (mode) { case PIPELINE.Fiducial: pipeline = new FiducialPipeline(xpcfComponentManager).AddTo(subscriptions); break; case PIPELINE.Natural: pipeline = new NaturalPipeline(xpcfComponentManager).AddTo(subscriptions); break; case PIPELINE.SLAM: pipeline = new SlamPipeline(xpcfComponentManager).AddTo(subscriptions); break; } overlay3D = xpcfComponentManager.Create("SolAR3DOverlayOpencv").BindTo <I3DOverlay>().AddTo(subscriptions); switch (source) { case SOURCE.SolAR: camera = xpcfComponentManager.Create("SolARCameraOpencv").BindTo <ICamera>().AddTo(subscriptions); var intrinsic = camera.getIntrinsicsParameters(); var distorsion = camera.getDistorsionParameters(); var resolution = camera.getResolution(); pipeline.SetCameraParameters(intrinsic, distorsion); overlay3D.setCameraParameters(intrinsic, distorsion); OnCalibrate?.Invoke(resolution, intrinsic, distorsion); if (camera.start() != FrameworkReturnCode._SUCCESS) { LOG_ERROR("Camera cannot start"); enabled = false; } break; case SOURCE.Unity: webcam = new WebCamTexture(); webcam.Play(); if (!webcam.isPlaying) { LOG_ERROR("Camera cannot start"); enabled = false; } break; } switch (display) { case DISPLAY.SolAR: // Set the size of the box to display according to the marker size in world unit var overlay3D_sizeProp = overlay3D.BindTo <IConfigurable>().getProperty("size"); var size = pipeline.GetMarkerSize(); overlay3D_sizeProp.setFloatingValue(size.width, 0); overlay3D_sizeProp.setFloatingValue(size.height, 1); overlay3D_sizeProp.setFloatingValue(size.height / 2.0f, 2); imageViewer = xpcfComponentManager.Create("SolARImageViewerOpencv").AddTo(subscriptions).BindTo <IImageViewer>().AddTo(subscriptions); break; case DISPLAY.Unity: break; } start = clock(); inputImage = SharedPtr.Alloc <Image>().AddTo(subscriptions); pose = new Transform3Df().AddTo(subscriptions); }
public static IDisposable RegisterGenericMotion(this View view, EventHandler <View.GenericMotionEventArgs> handler) { view.GenericMotion += handler; return(Disposable.Create(() => view.RunIfNativeInstanceAvailable(v => v.GenericMotion -= handler))); }
public IDisposable Subscribe(IObserver <bool> observer) { ProducerObserver = observer; NotifyProducer(); return(Disposable.Create(() => ProducerObserver = null)); }