This class supports throttling of multiple method calls to improve the responsiveness of an application. It delays a method call and skips all additional calls of this method during the delay. The call of the action is synchronized. It uses the current synchronization context that was active during creating this class.
This class is thread-safe.
コード例 #1
0
ファイル: ThrottledActionTest.cs プロジェクト: jbe2277/waf
        public void InvokeOnlyIfIdleForDelayTimeWithoutSynchronizationContext()
        {
            Assert.IsNull(SynchronizationContext.Current);

            int actionCallCount = 0;
            var throttledAction = new ThrottledAction(() => Interlocked.Add(ref actionCallCount, 1), ThrottledActionMode.InvokeOnlyIfIdleForDelayTime, TimeSpan.FromMilliseconds(100));
            Assert.IsFalse(throttledAction.IsRunning);

            throttledAction.InvokeAccumulated();
            Assert.IsTrue(throttledAction.IsRunning);
            throttledAction.InvokeAccumulated();
            throttledAction.InvokeAccumulated();

            // Multiple calls of InvokeAccumulated within the delayTime should call the action just once.
            Task.Delay(200).Wait();
            Assert.AreEqual(1, actionCallCount);
            Assert.IsFalse(throttledAction.IsRunning);

            actionCallCount = 0;
            throttledAction.InvokeAccumulated();
            Task.Delay(60).Wait();
            throttledAction.InvokeAccumulated();
            Task.Delay(60).Wait();
            throttledAction.InvokeAccumulated();
            Task.Delay(60).Wait();
            throttledAction.InvokeAccumulated();

            // Calls just once: The waits between InvokeAccumulated are less than the idle (delay) time.
            Task.Delay(200).Wait();
            Assert.AreEqual(1, actionCallCount);
            Assert.IsFalse(throttledAction.IsRunning);
        }
コード例 #2
0
 public WorkspaceController(IDocumentService documentService, Lazy<ShellViewModel> shellViewModel, Lazy<ErrorListViewModel> errorListViewModel, 
     Lazy<OutputViewModel> outputViewModel, ScriptHost host)
 {
     taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
     this.documentService = documentService;
     this.shellViewModel = shellViewModel;
     this.errorListViewModel = errorListViewModel;
     this.outputViewModel = outputViewModel;
     this.host = host;
     this.updateDiagnosticsAction = new ThrottledAction(UpdateDiagnostics, ThrottledActionMode.InvokeOnlyIfIdleForDelayTime, TimeSpan.FromSeconds(2));
     this.outputTextWriter = new DelegateTextWriter(AppendOutputText);
     this.errorTextWriter = new DelegateTextWriter(AppendErrorText);
     this.startCommand = new DelegateCommand(StartScript, CanStartScript);
     this.stopCommand = new DelegateCommand(StopScript, CanStopScript);
     this.documentIds = new Dictionary<DocumentFile, DocumentId>();
 }
コード例 #3
0
ファイル: ThrottledActionTest.cs プロジェクト: jbe2277/waf
        public void InvokeMaxEveryDelayTimeTestWithoutSynchronizationContext()
        {
            Assert.IsNull(SynchronizationContext.Current);
            
            int actionCallCount = 0;
            var throttledAction = new ThrottledAction(() => Interlocked.Add(ref actionCallCount, 1), ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(100));
            Assert.IsFalse(throttledAction.IsRunning);
            
            throttledAction.InvokeAccumulated();
            Assert.IsTrue(throttledAction.IsRunning);
            throttledAction.InvokeAccumulated();
            throttledAction.InvokeAccumulated();

            // Multiple calls of InvokeAccumulated within the delayTime should call the action just once.
            Task.Delay(200).Wait();
            Assert.AreEqual(1, actionCallCount);
            Assert.IsFalse(throttledAction.IsRunning);


            actionCallCount = 0;
            throttledAction.InvokeAccumulated();
            Task.Delay(10).Wait();
            throttledAction.InvokeAccumulated();
            Task.Delay(150).Wait();
            throttledAction.InvokeAccumulated();

            // Calls the action twice: First 2 InvokeAccumulated are within delayTime; Last is after delayTime.
            Task.Delay(200).Wait();
            Assert.AreEqual(2, actionCallCount);
            Assert.IsFalse(throttledAction.IsRunning);


            actionCallCount = 0;
            throttledAction.InvokeAccumulated();
            Task.Delay(10).Wait();
            throttledAction.Cancel();

            // Do not call the action because it is cancelled. 
            Task.Delay(200).Wait();
            Assert.AreEqual(0, actionCallCount);
            Assert.IsFalse(throttledAction.IsRunning);
        }
コード例 #4
0
        public PlayerView(PlayerService playerService)
        {
            this.InitializeComponent();
            this.viewModel = new Lazy<PlayerViewModel>(() => ViewHelper.GetViewModel<PlayerViewModel>(this));
            this.playerService = playerService;
            this.mediaPlayer = new MediaPlayer();
            this.duratonConverter = new Converters.DurationConverter();

            updateTimer = new DispatcherTimer();
            updateTimer.Interval = TimeSpan.FromMilliseconds(100);
            updateTimer.Tick += UpdateTimerTick;

            throttledSliderValueChangedAction = new ThrottledAction(ThrottledSliderValueChanged, ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(100));

            previousCommand = new DelegateCommand(Previous, CanPrevious);
            playPauseCommand = new DelegateCommand(PlayPause, CanPlayPause);
            nextCommand = new DelegateCommand(Next, CanNext);
            playerService.PreviousCommand = previousCommand;
            playerService.PlayPauseCommand = playPauseCommand;
            playerService.NextCommand = nextCommand;
            playerService.IsPlayCommand = true;
            
            Loaded += FirstTimeLoadedHandler;
        }
コード例 #5
0
ファイル: ThrottledActionTest.cs プロジェクト: jbe2277/waf
        public void InvokeMaxEveryDelayTimeTestWithSynchronizationContext()
        {
            using (var context = UnitTestSynchronizationContext.Create())
            {
                int actionCallCount = 0;
                var throttledAction = new ThrottledAction(() => Interlocked.Add(ref actionCallCount, 1), ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(100));
                Assert.IsFalse(throttledAction.IsRunning);

                throttledAction.InvokeAccumulated();
                Assert.IsTrue(throttledAction.IsRunning);
                throttledAction.InvokeAccumulated();
                throttledAction.InvokeAccumulated();

                // As long the unit test synchronization context is not executed the actionCallCount must not be increased.
                Task.Delay(200).Wait();
                Assert.AreEqual(0, actionCallCount);

                // Execute the unit test synchronization context.
                context.WaitFor(() => actionCallCount > 0, TimeSpan.FromMilliseconds(200));
                Assert.AreEqual(1, actionCallCount);
                Assert.IsFalse(throttledAction.IsRunning);
            }
        }
コード例 #6
0
ファイル: ThrottledActionTest.cs プロジェクト: jbe2277/waf
 public void ConstructorTest()
 {
     AssertHelper.ExpectedException<ArgumentNullException>(() => new ThrottledAction(null));
     var throttledAction = new ThrottledAction(() => { });
     Assert.IsFalse(throttledAction.IsRunning);
 }