public Task <INotifyDisposable> Lock() { //if (we are not locked) //{ // return Task that is already finished //} else { // create task completion source, so we can return the token later // and return the task //} lock (_mutex) { var token = Disposables.Call(Release); if (_currentToken == null) { _currentToken = token; return(_currentToken.ToTask()); } else { var drt = token.ToDeferredTask(); _requests.Enqueue(drt); return(drt.Task); } } }
public static IObservable <T> AsObservable <T>(this INotifyDisposable disposable, Func <T> lastValue = null) { return(Observable.Create <T>(observer => { if (disposable.IsDisposed) { if (lastValue != null) { observer.OnNext(lastValue()); } observer.OnCompleted(); return Disposables.Empty; } var handler = Disposables.Call(() => { if (lastValue != null) { observer.OnNext(lastValue()); } observer.OnCompleted(); }); disposable.Attach(handler, keepAlive: true); return Disposables.Call(() => { disposable.Dettach(handler); }); })); }
/// <summary> /// Creates an observable that yields an event when the property value changes. The event payload is the new /// property value. /// </summary> public static IObservable <TProp> ObservePropertyValues <TBindable, TProp>( this TBindable owner, Expression <Func <TBindable, TProp> > property ) where TBindable : BindableBase { var propInfo = property.GetProperty(); var getter = propInfo.AsGetter <TBindable, TProp>(); var value = getter(owner); return(Observable.Create <TProp>(observer => { owner.Observe <TProp>(propInfo.Name, val => observer.OnNext(val)); var handler = Disposables.Call(() => observer.OnCompleted()); owner.Attach(handler); observer.OnNext(getter(owner)); return Disposables.Call(() => { owner.Unobserve(propInfo.Name, owner); owner.Dettach(handler); }); }).ObserveOnDispatcher()); }
public static INotifyDisposable WhenDisposed(this INotifyDisposable source, Action action) { var call = Disposables.Call(action); source.Attach(call, keepAlive: true); return(source); }
public Task <INotifyDisposable> Lock() { lock (_mutex) { var token = Disposables.Call(Release); if (LocksCount < LocksLimit) { _currentTokens.Add(token); return(token.ToTask()); } else { var drt = token.ToDeferredTask(); _queue.Enqueue(drt); return(drt.Task); } } }
/// <summary> /// Converts an AsyncEvent to IObservable of Unit (since there is not IObservable of void. Using the /// owner to control the weak action lifespan and unsubscribe when observer is disposed /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TOwner"></typeparam> /// <param name="source"></param> /// <param name="owner"></param> /// <returns></returns> public static IObservable <Unit> ToObservable <TOwner>(this AsyncEvent source, TOwner owner) where TOwner : INotifyDisposable { return(Observable.Create <Unit>(async observer => { Func <Task> handler = () => { observer.OnNext(Unit.Default); return Task.CompletedTask; }; await source.Subscribe(owner, handler); return Disposables.Call(() => { source.Unsubscribe(owner, handler); }); })); }
/// <summary> /// Subscribes to an IStateCollectionReader and exposes it as Observable of CollectionChanges /// </summary> public static IObservable <CollectionChanges <T> > ObserveChanges <T, TOwner>(this IStateCollectionReader <T> source, TOwner owner) where TOwner : INotifyDisposable { return(Observable.Create <CollectionChanges <T> >(async observer => { Func <CollectionChanges <T>, Task> handler = val => { observer.OnNext(val); return Task.CompletedTask; }; await source.Changed.Subscribe(owner, handler); return Disposables.Call(() => { source.Changed.Unsubscribe(owner, handler); }); })); }
public Task <IDisposable> WriterLock() { lock (_mutex) { var token = Disposables.Call(Release, LockState.Write); if (CurrentState == LockState.None) { // only if there are no locks at the moment _currentTokens.Add(token); return(token.ToTask <IDisposable>()); } else { var drt = token.ToDeferredTask <IDisposable>(); _writerQueue.Enqueue(drt); return(drt.Task); } } }
public Task <IDisposable> ReaderLock() { lock (_mutex) { var token = Disposables.Call(Release, LockState.Read); if (CurrentState < LockState.Write) { // read or none _currentTokens.Add(token); return(token.ToTask <IDisposable>()); } else { var drt = token.ToDeferredTask <IDisposable>(); _readerQueue.Enqueue(drt); return(drt.Task); } } }