用于ViewModel更新的TimerEvent中的无线跨线程访问

时间:2014-06-04 20:55:57

标签: c# windows-phone-8

我有一个带有Load() - Method的ViewModel(ObservableCollection)。在我的UI中,我有一个“Reload”-Button,它调用Load() - Method。到这里一切都很好。

ViewModel在App.xaml.cs中声明,因此可以全局访问。

现在我想独立于用户交互更新ViewModel。我按如下方式创建了一个Timer:

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;
    }
}

当Timer运行时,我收到错误:Invalid cross-thread Access。正在搜索我发现的可能的解决方案,我必须invoke。我该怎么做呢如果我这样做,我怎么能避免用户在定时器运行时按下“更新”-Button?

更新:

这不起作用:

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

我不能在那里使用await,但我必须因为在内部调用Web Api。

1 个答案:

答案 0 :(得分:1)

解决这个问题的方法很多。根据注释,最简单的方法是使用Dispatcher更新UI线程上的ObservableCollection。

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