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

编程入门 行业动态 更新时间:2024-10-23 17:23:50
本文介绍了用于 ViewModel 更新的 TimerEvent 中的跨线程访问无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我有一个带有 Load() 方法的 ViewModel (ObservableCollection).在我的用户界面中,我有一个调用 Load()-Method 的重新加载"按钮.到这里一切都很好.

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.

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

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

现在我想独立于用户交互更新 ViewModel.我创建了一个计时器,如下所示:

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

当计时器运行时,我收到一个错误:无效的跨线程访问.寻找可能的解决方案,我发现,我必须invoke.我该怎么做.如果我这样做,如何避免用户在计时器运行时按下更新"按钮?

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?

更新:

这不起作用:

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

我不能在那里使用 await,但我必须在里面调用 Web Api.

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

推荐答案

有很多方法可以解决这个问题.根据评论,最简单的方法是使用 Dispatcher 更新 UI 线程上的 ObservableCollection.

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

这篇关于用于 ViewModel 更新的 TimerEvent 中的跨线程访问无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

更多推荐

[db:关键词]

本文发布于:2023-04-25 13:37:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1117541.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   ViewModel   TimerEvent

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!