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(); }
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(); }
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); }
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); }
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); }
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; } }
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); }); }
/// <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)); }
public static extern void wait(SessionHandle session, IntPtr task_completion_source, ProgressDirection direction, out NativeException ex);
public static extern ulong register_progress_notifier(SessionHandle session, IntPtr token_ptr, ProgressDirection direction, [MarshalAs(UnmanagedType.U1)] bool is_streaming, out NativeException ex);
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)); } } }); }
public static void SetDirection(ProgressBar progressBar, ProgressDirection value) { progressBar.SetValue(DirectionProperty, value); }
internal void SetDirection(ProgressDirection direction) { this.direction = direction; }
public SyncProgressObservable(Session session, ProgressDirection direction, ProgressMode mode) { _session = session; _direction = direction; _mode = mode; }
/// <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); }