예제 #1
0
        public IndefiniteProgressBar(char moverChar = '=', char backgroundChar = '-', int?moverWidth = null, ProgressDirection direction = ProgressDirection.LeftToRight, object consoleLock = null)
        {
            _moverChar      = moverChar;
            _backgroundChar = backgroundChar;
            _direction      = direction;
            _moverWidth     = moverWidth ?? Console.BufferWidth / 2;

            if (Console.CursorLeft > 0)
            {
                Console.WriteLine();
            }

            _bufferWidth = Console.BufferWidth;
            _cursorTop   = Console.CursorTop;
            _consoleLock = consoleLock;

            if (_consoleLock == null)
            {
                _consoleLock = new object();
            }

            var tick = 0;

            _timer.Elapsed += (o, ea) =>
            {
                lock (_consoleLock)
                {
                    Print(_action, tick);
                }

                tick++;
            };
            _timer.Start();
        }
예제 #2
0
        public void Wait(TaskCompletionSource <object> tcs, ProgressDirection direction)
        {
            var tcsHandle = GCHandle.Alloc(tcs);

            NativeMethods.wait(this, GCHandle.ToIntPtr(tcsHandle), direction, out var ex);
            ex.ThrowIfNecessary();
        }
예제 #3
0
        public ulong RegisterProgressNotifier(GCHandle managedHandle, ProgressDirection direction, ProgressMode mode)
        {
            var isStreaming = mode == ProgressMode.ReportIndefinitely;
            var token       = NativeMethods.register_progress_notifier(this, GCHandle.ToIntPtr(managedHandle), direction, isStreaming, out var ex);

            ex.ThrowIfNecessary();
            return(token);
        }
예제 #4
0
        public bool Wait(TaskCompletionSource <object> tcs, ProgressDirection direction)
        {
            var             tcsHandle = GCHandle.Alloc(tcs);
            NativeException ex;
            var             result = NativeMethods.wait(this, GCHandle.ToIntPtr(tcsHandle), direction, out ex);

            ex.ThrowIfNecessary();
            return(result);
        }
예제 #5
0
        public ulong RegisterProgressNotifier(IntPtr tokenPtr, ProgressDirection direction, ProgressMode mode)
        {
            NativeException ex;
            var             isStreaming = mode == ProgressMode.ReportIndefinitely;
            var             token       = NativeMethods.register_progress_notifier(this, tokenPtr, direction, isStreaming, out ex);

            ex.ThrowIfNecessary();
            return(token);
        }
예제 #6
0
        public async Task WaitAsync(ProgressDirection direction)
        {
            var tcs       = new TaskCompletionSource <object>();
            var tcsHandle = GCHandle.Alloc(tcs);

            try
            {
                NativeMethods.wait(this, GCHandle.ToIntPtr(tcsHandle), direction, out var ex);
                ex.ThrowIfNecessary();

                await tcs.Task;
            }
            finally
            {
                tcsHandle.Free();
            }
        }
 public ProgressNotificationToken(Session session,
                                  IObserver <SyncProgress> observer,
                                  ProgressDirection direction,
                                  ProgressMode mode)
 {
     _session  = session;
     _observer = observer;
     _gcHandle = GCHandle.Alloc(this);
     try
     {
         _nativeToken = _session.Handle.RegisterProgressNotifier(GCHandle.ToIntPtr(_gcHandle), direction, mode);
     }
     catch
     {
         _gcHandle.Free();
         throw;
     }
 }
예제 #8
0
        public void Session_ProgressObservable_UnitTests(ProgressDirection direction, ProgressMode mode)
        {
            AsyncContext.Run(async() =>
            {
                var callbacksInvoked = 0;
                var completionTCS    = new TaskCompletionSource <ulong>();

                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();

                session.SimulateProgress(0, 100, 0, 100);

                var observable = session.GetProgressObservable(direction, mode);
                var token      = observable.Subscribe(p =>
                {
                    try
                    {
                        callbacksInvoked++;

                        Assert.That(p.TransferredBytes, Is.LessThanOrEqualTo(p.TransferableBytes));

                        if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                        {
                            Assert.That(p.TransferableBytes, Is.EqualTo(100));
                        }
                    }
                    catch (Exception e)
                    {
                        completionTCS.TrySetException(e);
                    }

                    if (p.TransferredBytes == p.TransferableBytes)
                    {
                        completionTCS.TrySetResult(p.TransferredBytes);
                    }
                });

                session.SimulateProgress(50, 150, 50, 150);
                await Task.Delay(50);

                session.SimulateProgress(100, 200, 100, 200);
                await Task.Delay(50);

                session.SimulateProgress(150, 200, 150, 200);
                await Task.Delay(50);

                session.SimulateProgress(200, 200, 200, 200);
                await Task.Delay(50);

                var totalTransferred = await completionTCS.Task;

                if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                {
                    Assert.That(totalTransferred, Is.EqualTo(100));
                    Assert.That(callbacksInvoked, Is.EqualTo(3));
                }
                else
                {
                    Assert.That(totalTransferred, Is.EqualTo(200));
                    Assert.That(callbacksInvoked, Is.EqualTo(5));
                }

                token.Dispose();
                realm.Dispose();
                Realm.DeleteRealm(realm.Config);
            });
        }
예제 #9
0
 /// <summary>
 /// Gets an <see cref="IObservable{T}"/> that can be used to track upload or download progress.
 /// </summary>
 /// <remarks>
 /// To start receiving notifications, you should call <see cref="IObservable{T}.Subscribe"/> on the returned object.
 /// The token returned from <see cref="IObservable{T}.Subscribe"/> should be retained as long as progress
 /// notifications are desired. To stop receiving notifications, call <see cref="IDisposable.Dispose"/>
 /// on the token.
 /// You don't need to keep a reference to the observable itself.
 /// The progress callback will always be called once immediately upon subscribing in order to provide
 /// the latest available status information.
 /// </remarks>
 /// <returns>An observable that you can subscribe to and receive progress updates.</returns>
 /// <param name="direction">The transfer direction (upload or download) to track in the subscription callback.</param>
 /// <param name="mode">The desired behavior of this progress notification block.</param>
 /// <example>
 /// <code>
 /// class ProgressNotifyingViewModel
 /// {
 ///     private IDisposable notificationToken;
 ///
 ///     public void ShowProgress()
 ///     {
 ///         var observable = session.GetProgressObservable(ProgressDirection.Upload, ProgressMode.ReportIndefinitely);
 ///         notificationToken = observable.Subscribe(progress =>
 ///         {
 ///             // Update relevant properties by accessing
 ///             // progress.TransferredBytes and progress.TransferableBytes
 ///         });
 ///     }
 ///
 ///     public void HideProgress()
 ///     {
 ///         notificationToken?.Dispose();
 ///         notificationToken = null;
 ///     }
 /// }
 /// </code>
 /// In this example we're using <see href="https://msdn.microsoft.com/en-us/library/ff402849(v=vs.103).aspx">ObservableExtensions.Subscribe</see>
 /// found in the <see href="https://github.com/Reactive-Extensions/Rx.NET">Reactive Extensions</see> class library.
 /// If you prefer not to take a dependency on it, you can create a class that implements <see cref="IObserver{T}"/>
 /// and use it to subscribe instead.
 /// </example>
 public IObservable <SyncProgress> GetProgressObservable(ProgressDirection direction, ProgressMode mode)
 {
     return(new SyncProgressObservable(this, direction, mode));
 }
예제 #10
0
 public static extern void wait(SessionHandle session, IntPtr task_completion_source, ProgressDirection direction, out NativeException ex);
예제 #11
0
 public static extern ulong register_progress_notifier(SessionHandle session,
                                                       IntPtr token_ptr,
                                                       ProgressDirection direction,
                                                       [MarshalAs(UnmanagedType.U1)] bool is_streaming,
                                                       out NativeException ex);
예제 #12
0
        public void Session_ProgressObservable_UnitTests(ProgressDirection direction, ProgressMode mode)
        {
            AsyncContext.Run(async() =>
            {
                var callbacksInvoked = 0;
                var completionTCS    = new TaskCompletionSource <ulong>();

                var config  = await SyncTestHelpers.GetFakeConfigAsync();
                var realm   = GetRealm(config);
                var session = GetSession(realm);

                session.SimulateProgress(0, 100, 0, 100);

                var observable = session.GetProgressObservable(direction, mode);
                var token      = observable.Subscribe(p =>
                {
                    try
                    {
                        callbacksInvoked++;

                        // .NET Core dislikes asserts in the callback so much it crashes.
                        if (p.TransferredBytes > p.TransferableBytes)
                        {
                            throw new Exception("TransferredBytes must be less than or equal to TransferableBytes");
                        }

                        if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                        {
                            if (p.TransferableBytes != 100)
                            {
                                throw new Exception("TransferableBytes must be equal to 100");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        completionTCS.TrySetException(e);
                    }

                    if (p.TransferredBytes == p.TransferableBytes)
                    {
                        completionTCS.TrySetResult(p.TransferredBytes);
                    }
                });

                using (token)
                {
                    session.SimulateProgress(50, 150, 50, 150);
                    await Task.Delay(50);

                    session.SimulateProgress(100, 200, 100, 200);
                    await Task.Delay(50);

                    session.SimulateProgress(150, 200, 150, 200);
                    await Task.Delay(50);

                    session.SimulateProgress(200, 200, 200, 200);
                    await Task.Delay(50);

                    var totalTransferred = await completionTCS.Task;

                    if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                    {
                        Assert.That(totalTransferred, Is.EqualTo(100));
                        Assert.That(callbacksInvoked, Is.EqualTo(3));
                    }
                    else
                    {
                        Assert.That(totalTransferred, Is.EqualTo(200));
                        Assert.That(callbacksInvoked, Is.EqualTo(5));
                    }
                }
            });
        }
예제 #13
0
 public static void SetDirection(ProgressBar progressBar, ProgressDirection value)
 {
     progressBar.SetValue(DirectionProperty, value);
 }
예제 #14
0
 internal void SetDirection(ProgressDirection direction)
 {
     this.direction = direction;
 }
 public SyncProgressObservable(Session session, ProgressDirection direction, ProgressMode mode)
 {
     _session   = session;
     _direction = direction;
     _mode      = mode;
 }
예제 #16
0
 /// <summary>
 /// Gets an <see cref="IObservable{T}"/> that can be used to track upload or download progress.
 /// </summary>
 /// <remarks>
 /// To start receiving notifications, you should call <see cref="IObservable{T}.Subscribe"/> on the returned object.
 /// The token returned from <see cref="IObservable{T}.Subscribe"/> should be retained as long as progress
 /// notifications are desired. To stop receiving notifications, call <see cref="IDisposable.Dispose"/>
 /// on the token.
 /// You don't need to keep a reference to the observable itself.
 /// The progress callback will always be called once immediately upon subscribing in order to provide
 /// the latest available status information.
 /// </remarks>
 /// <returns>An observable that you can subscribe to and receive progress updates.</returns>
 /// <param name="direction">The transfer direction (upload or download) to track in the subscription callback.</param>
 /// <param name="mode">The desired behavior of this progress notification block.</param>
 /// <example>
 /// <code>
 /// class ProgressNotifyingViewModel
 /// {
 ///     private IDisposable notificationToken;
 ///
 ///     public void ShowProgress()
 ///     {
 ///         var observable = session.GetProgressObservable(ProgressDirection.Upload, ProgressMode.ReportIndefinitely);
 ///         notificationToken = observable.Subscribe(progress =>
 ///         {
 ///             // Update relevant properties by accessing
 ///             // progress.TransferredBytes and progress.TransferableBytes
 ///         });
 ///     }
 ///
 ///     public void HideProgress()
 ///     {
 ///         notificationToken?.Dispose();
 ///         notificationToken = null;
 ///     }
 /// }
 /// </code>
 /// In this example we're using <see href="https://msdn.microsoft.com/en-us/library/ff402849(v=vs.103).aspx">ObservableExtensions.Subscribe</see>
 /// found in the <see href="https://github.com/Reactive-Extensions/Rx.NET">Reactive Extensions</see> class library.
 /// If you prefer not to take a dependency on it, you can create a class that implements <see cref="IObserver{T}"/>
 /// and use it to subscribe instead.
 /// </example>
 public IObservable <SyncProgress> GetProgressObservable(ProgressDirection direction, ProgressMode mode)
 {
     RealmPCLHelpers.ThrowProxyShouldNeverBeUsed();
     return(null);
 }