WPF,我怎么能只用一个DispatcherTimer打勾

时间:2015-01-27 08:20:58

标签: c# wpf

我想拥有一个在几秒钟后运行一次的功能。 (程序没有停止)

所以我正在使用DispatcherTimer这样的

private void Button_Click(object sender, RoutedEventArgs e)
{
    TimerStart();
}

DispatcherTimer Timer1 = new DispatcherTimer();
int count = 3;
private void TimerStart()
{
    Timer1.Interval = new TimeSpan(0, 0, 3);
    Timer1.Tick += MyEvent;
    Timer1.Start();
}

void MyEvent(object sender, EventArgs e)
{
    MessageBox.Show(count.ToString());
    // My code
    (sender as DispatcherTimer).Stop();
    count++;
}

在第一个ButtonClick中,它在3秒内运行MyEvent()

第二次ButtonClick执行两次,3秒后调用MyEvent()

第三次,MyEvent()三次运行MyEvent()

为什么会这样?

所以我尝试了一种不同的方法,使用Thread:

private void Button_Click(object sender, RoutedEventArgs e)
    {
        System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(
            delegate()
            {
                System.Threading.Thread.Sleep(2000);
                // my code
                count++;
            }));

        thread.Start();
    }

但是这样,错误发生在MyCode (this.Usercontrol.Children.RemoveAt(0);)

的一部分中
  

System.InvalidOperationException:   其他线程不能是拥有该对象的线程,调用该对象>访问

我该怎么办?

谢谢你,问候。

2 个答案:

答案 0 :(得分:1)

首先,你应该理解这段代码:

 Timer1.Tick += MyEvent;

+=表示注册某个活动。 例如,在第一个ButtonClick中,Timer1将名为MyEvent的事件注册为Tick。在第二次点击中,Timer1再次注册MyEvent,这意味着Timer1重新注册MyEvent两次。所以你会看到MyEvent两次出局。

您可以编写如下代码:

    public MainWindow()
    {
        InitializeComponent();
        Timer1 = new DispatcherTimer();
        Timer1.Tick += MyEvent;
        Timer1.Interval = new TimeSpan(0, 0, 3);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Timer1.Start();
    }

    DispatcherTimer Timer1;
    int count = 3;

    void MyEvent(object sender, EventArgs e)
    {
        MessageBox.Show(count.ToString());
        // My code
        (sender as DispatcherTimer).Stop();
        count++;
    }

Timer1仅在Constructer中注册一次MyEvent,因此它是正确的。

答案 1 :(得分:0)

Timer1.Tick += MyEvent;移除TimerStart()。每次调用MyEvent()时,都会导致TickTimerStart()事件的调用列表中注册。 Tick事件的InvocationList将包含与注册它的次数相同的函数。

将事件注册移动到构造函数,它将正常工作。