示例#1
0
        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);
                }
            }
        }
示例#2
0
        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);
                });
            }));
        }
示例#3
0
        /// <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());
        }
示例#4
0
        public static INotifyDisposable WhenDisposed(this INotifyDisposable source, Action action)
        {
            var call = Disposables.Call(action);

            source.Attach(call, keepAlive: true);

            return(source);
        }
示例#5
0
 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);
         }
     }
 }
示例#6
0
        /// <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);
                });
            }));
        }
示例#7
0
        /// <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);
                });
            }));
        }
示例#8
0
 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);
         }
     }
 }
示例#9
0
 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);
         }
     }
 }