问题
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