Multithreading – using dispatcher in unit testable MVVM code

I have an MVVM Lite application and I want unit testability The model uses system Timers. Timer, so the update event is finally on the background worker thread The unit test is good, but the system. Exe is thrown at run time Notsupportedexception "this type of collectionview does not support changing its sourcecollection from a different thread than the dispatcher thread." I wanted the MVVM Lite class threading Dispatcherhelper can solve the problem, but call dispatcherhelper Checkbegininvokeonui caused my unit test to fail This is the code I finally got in the view model

private void locationChangedHandler(object src,LocationChangedEventArgs e)
{
    if (e.LocationName != this.CurrentPlaceName)
    {
        this.CurrentPlaceName = e.LocationName;
        List<FileInfo> filesTaggedForHere = Tagger.FilesWithTag(this.CurrentPlaceName);

        //This nextline fixes the threading error,but breaks it for unit tests
        //GalaSoft.MvvmLight.Threading.DispatcherHelper.CheckBeginInvokeOnUI(delegate { updateFilesIntendedForHere(filesTaggedForHere); });

        if (Application.Current != null)
        {
            this.dispatcher.Invoke(new Action(delegate { updateFilesIntendedForHere(filesTaggedForHere); }));
        }
        else
        {
            updateFilesIntendedForHere(filesTaggedForHere);
        }
    }
}
private void updateFilesIntendedForHere(List<FileInfo> filesTaggedForHereIn)
{
    this.FilesIntendedForHere.Clear();
    foreach (FileInfo file in filesTaggedForHereIn)
    {
        if (!this.FilesIntendedForHere.Contains(file))
        {
            this.FilesIntendedForHere.Add(file);
        }
    }
}

I am here http://kentb.blogspot.com/2009/04/mvvm-infrastructure-viewmodel.html I tried this technique in, but I tried it on dispatcher during unit testing The invoke call on the currentdispatcher failed because it could not run This is why I call helper methods directly when running tests instead of applications

This may not be right – the ViewModel should not care where it is called Anyone can see why Kent boogaart's scheduler method and MVVM Lite dispatcher helper Checkbegininvokeonui doesn't work in my unit test?

Solution

I did this:

class Myviewmodel() {
    private readonly SynchronizationContext _syncContext;

    public Myviewmodel() {
        _syncContext = SynchronizationContext.Current; // or use DI
    )

    ...

    public void SomeTimerEvent() {
        _syncContext.Post(_ => UpdateUi(),null);
    }
}

The default context will be the thread pool in the test and the scheduler in the UI If you want other behaviors, you can easily create your own test context

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>