c# - 在 Timer.Elapsed 事件上更新 MainWindow

标签 c# wpf

我正在编写一个家庭 WPF 应用程序,它以配置的时间间隔从服务器获取文件。

这是一个基本窗口,带有几个标签。我有以下内容

  • 开始时间(反射(reflect)“开始”事件被击中的日期时间
  • 持续时间(反射(reflect)应用已运行的时间)
  • 速度(文件的下载速度)

我想每秒更新主窗口上的持续时间,所以我有以下代码来执行此操作(在单独的类“RunDownloader.cs”中)。

    private void StartTickTimer()
    {
        const double interval = 1000;

        if (_tickTimer == null)
        {
            _tickTimer = new Timer
            {
                Interval = interval
            };
            _tickTimer.Elapsed += _ticktimer_Elapsed;
        }

        _tickTimer.Start();
    }

在 _ticktimer_Elapsed 上我在主窗口中调用一个方法 _mainWindow.UpdateTicker();

这会执行以下操作。

    public void UpdateTicker()
    {
        var timeStarted = lblTimeStarted.Content.ToString();
        DateTime startTime = DateTime.Parse(timeStarted);
        TimeSpan span = DateTime.Now.Subtract(startTime);

        //ToDo: Output time taken here!
        //lblTimeElapsed.Content =
    }

我有两个问题。

  1. 调用 lblTimeStarted.Content.ToString() 时出现以下异常;在 UpdateTicker() 中

        "The calling thread cannot access this object because a different thread owns it."
    
  2. 我不太清楚,如何从 TimeSpan 正确显示 lblTimeElapsed.Content 的持续时间

提前感谢您的任何回答。 :D

最佳答案

在 WPF 中,您不能从 UI 线程以外的线程更新 UI 对象(在 UI 线程上创建)。
为了从其他线程(例如计时器线程)更新 UI 控件,您需要使用 Dispatcher 在 UI 线程上运行更新代码。
Question/answer可能会对您有所帮助,或者您可以通过谷歌搜索“WPF Dispatcher”找到大量信息。
调度程序调用示例 - lamda 代码将发布以在 UI 线程上运行:

Dispatcher.BeginInvoke(new Action(() =>
{
    text_box.AppendText(formated_msg);
    text_box.ScrollToEnd();
}));

或者,您可以将现有计时器替换为 DispatchTimer - 与您使用的计时器不同,它确保计时器回调在 UI 线程上:

Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set on the DispatcherTimer.

关于c# - 在 Timer.Elapsed 事件上更新 MainWindow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10267956/

相关文章:

c# - 使用 Jenkins 的 Roslyn 分析器

c# - 强制 VB.NET 生成与 C# 相同的字符串比较表达式?

c# - Server.MapPath 在当前上下文中不存在

c# - 修改上传文件从Api到Api

wpf - WPF TabControl : Mouse click event on (empty area of) tab bar

c# - 为什么我的 listboxitems 不折叠?

c# - 将参数传递给 MVVM 命令

c#:在完成之前经过一定时间后重新启动异步任务

c# - 在 WPF 中将参数传递给 StartupUri

c# - 如何将 DataGridComboBoxColumn 的数据上下文更改为特定类?