Invalid cross-thread access in TimerEvent for ViewModel update

一世执手 提交于 2019-12-25 12:12:04

问题


I have a ViewModel (ObservableCollection) with a Load()-Method. In my UI I have a "Reload"-Button that calls the Load()-Method. Till here everything is fine.

The ViewModel is declared in App.xaml.cs so it´s globally accessible.

Now I want to update the ViewModel independent of user interaction. I created a Timer as follows:

public static class WhagooBackgroundManager
{
    private static bool _isInitialized = false;
    private static bool _isRunning = false;
    private static Timer _AppTimer;
    private static int _runcounter = 0;
    private static DateTime _lastRun = DateTime.MinValue;

    public static void Initialize(int pIntervall)
    {
        if (_isInitialized == false)
        {
            _isInitialized = true;
            // Init the timer - it will call OnTimerTick every "pIntervall" secods, passing null as argument to the method.
            _AppTimer = new Timer(OnTimerTick, null, pIntervall * 1000, pIntervall * 1000);
        }
    }

    private static void OnTimerTick(object state)
    {
        _runcounter = _runcounter + 1;
        // Exit if still running:
        if (_isRunning == true)
        {
            _currentstatus = "Skipped Execution, still running";
            return;
        }
        // Executing Main-Routine:
        GetLocation();
        _lastRun = DateTime.UtcNow;
    }

    private static async void GetLocation()
    {
        _isRunning = true;
        // Viewmodels updaten:
        await App.ViewSuggestionsData.LoadData();
        }
        _isRunning = false;
    }
}

When Timer runs, I get an Error: Invalid cross-thread Access. Searching for possible Solutions I found out, that I have to invoke. How do I do this exactly. And if I do this, how can I avoid that a user is pressing the "Update"-Button while Timer is running?

UPDATE:

This don´t work:

Deployment.Current.Dispatcher.BeginInvoke( () => { 
    await App.ViewSuggestionsData.LoadData();
});

I can´t use await there, but I must because of calling Web Api inside.


回答1:


Lots of ways to solve this. Based on the comments the simplest way would be updating the ObservableCollection on the UI thread using the Dispatcher.

async Task LoadData()
{
    // do some stuff
    var data = await SomeWebCall();
    Deployment.Current.Dispatcher.BeginInvoke( () => {
        MyObservableCollection = data; // or new ObservableCollection(data);
    });
}


来源:https://stackoverflow.com/questions/24047407/invalid-cross-thread-access-in-timerevent-for-viewmodel-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!