计时器回调关闭WPF应用程序(DispatcherTimer工程..) [英] Timer callback closes WPF app (DispatcherTimer works..)

查看:836
本文介绍了计时器回调关闭WPF应用程序(DispatcherTimer工程..)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF应用程序与显示当前时间的文本块。据说文本块被绑定到视图模型一个的DependencyProperty。当然,我需要不断更新的时间,所以我用一个计时器(System.Threading.Timer)像这样:

I have a WPF app with a textblock that displays the current time. Said textblock is bound to a DependencyProperty on the ViewModel. Naturally I need to keep updating the time, so I used a timer (System.Threading.Timer) like so:

public MainViewModel()
{
    _dateTimer = new Timer(_dateTimer_Tick, null, 0, 60000);
}

void _dateTimer_Tick(object sender)
{
    Time = DateTime.Now.ToString("HH:mm");
    Date = DateTime.Now.ToString("D");
}

的事情是,当回调被调用时,应用程序退出...长号(输出说:第一个机会异常'System.InvalidOperationException'类型的出现在WindowsBase.dll只是当它是即将写入时间DP)。

The thing is, when the callback is called, the app exits... bummer (output says: "A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll" just when it's about to write to the Time DP).

如果我用一个DispatcherTimer一切工作正常。我不介意使用DispatcherTimer,它只是该应用程序是相当大的,我想调整其性能尽我所能。至于我可以看到我没有访问UI线程(我只是更新的属性),所以DispatcherTimer就没有必要。

If I use a DispatcherTimer everything works fine. I don't mind using a DispatcherTimer, it's just that the app is quite big and I wanted to tweak out its performance the best I could. As far as I can see I'm not accessing the UI thread (I'm just updating a property) so a DispatcherTimer wouldn't be needed.

我缺少的东西?

感谢。

编辑: 这些属性的定义是这样的:

The properties are defined like this:

    public string Time
    {
        get { return (string)GetValue(TimeProperty); }
        set { SetValue(TimeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Time.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TimeProperty =
        DependencyProperty.Register("Time", typeof(string), typeof(MainViewModel), new UIPropertyMetadata(""));

(日期是相同的)

(Date is the same)

推荐答案

定时器回调的是,螺纹这是不UI线程被执行时,这会导致问题;这是发生在尽管事实上,你'只更新属性的原因是因为这种调用创建一个调用链,即更改通知有关方面的属性,在这种情况下是UI,因此范围冒泡造成不适当的跨线程调用。

The timer callback is being executed on a thread which is not the UI thread, this causes problems; the reason this is occurring in spite of the fact that you're 'only updating a property' is because such a call creates a chain of calls, namely to notify interested parties of changes to a property, which in this case is the UI, and consequently the scope bubbles up to cause inappropriate cross-thread calls.

要克服这一点,你可以在计时器构造函数的参数指定调度窗口的在状态参数,然后使用 Dispatcher.Invoke

To get over this, you can specify the Dispatcher of your Window in the timer constructor as the argument for the state parameter, then use Dispatcher.Invoke.

例如...

public MainViewModel()
{
    _dateTimer = new Timer(_dateTimer_Tick, Dispatcher, 0, 60000);
}

void _dateTimer_Tick(object state)
{
    ((Dispatcher)state).Invoke(UpdateUI);
}

void UpdateUI()
{
    Time = DateTime.Now.ToString("HH:mm");
    Date = DateTime.Now.ToString("D");
}

编辑:

使用 DispatcherTimer ,所建议的亨克,甚至认为是自己,很可能是要走的路在这里,但是 - 我根本不知道的类型,因此在任何位置,我的答案来证明。至于在 DispatcherTimer 和性能,以何种理由您的担忧是成立?

Using a DispatcherTimer, as suggested by Henk, and even considered by yourself, may well be the way to go here, however - I simply wasn't aware of the type and therefore was in no position to demonstrate in my answer. With regards to the DispatcherTimer and performance, on what grounds is your concern founded?

这篇关于计时器回调关闭WPF应用程序(DispatcherTimer工程..)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆