2

I have a class with RefreshAsync method which can take a long time to execute. I am using Mvvm light framework. I need to call it after object created but not everytime when I get it's instance from servicelocator

var vm = ServiceLocator.Current.GetInstance<FileSystemViewModel>();

So I use DispatcherTimer to create deferred update logic. But it does not fire and I don't know why.

Here is the code

private DispatcherTimer _timer;

public FileSystemViewModel()
{
    _timer = new DispatcherTimer(DispatcherPriority.Send) {Interval = TimeSpan.FromMilliseconds(20)};
    _timer.Tick += DefferedUpdate;
    _timer.Start();
}

private async void DefferedUpdate(object sender, EventArgs e)
{
    (sender as DispatcherTimer)?.Stop();
    await RefreshAsync().ConfigureAwait(false);
}
the-noob
  • 1,322
  • 2
  • 14
  • 19
Anton
  • 339
  • 2
  • 15
  • And what if I create DispatcherTimer instance in DispatcherHelper.CheckBeginInvokeOnUI(() => ...) ? Will it work? – Anton Jul 24 '16 at 18:09

1 Answers1

3

Creating a DispatcherTimer must be done from a thread with an active Dispatcher or by passing an active dispatcher to the timer's constructor, e.g.

new DispatcherTimer(Application.Current.Dispatcher)

You should also consider if you really need a DispatcherTimer... A view model could most of the time do with a regular timer (e.g. System.Timers.Timer). Or in your case, even better - a simple Task.Delay in the async method:

private async Task DefferedUpdate()
{
    await Task.Delay(TimeSpan.FromMilliseconds(20)).ConfigureAwait(false);
    await RefreshAsync().ConfigureAwait(false);
}
Eli Arbel
  • 22,391
  • 3
  • 45
  • 71