WPF,如何使用 DispatcherTimer 只勾选一次

WPF, How can I only one tick using a DispatcherTimer

我想要一个在几秒后运行一次的函数。 (节目不停)

所以我正在使用这样的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()

为什么会这样?

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

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 : Other threads can not be the thread that owns the object, call the object >access

我该怎么办?

谢谢,问候。

首先你要理解这段代码:

 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,所以是正确的。

TimerStart() 中删除 Timer1.Tick += MyEvent;。这导致每次调用 TimerStart() 时,MyEvent() 都被注册到 Tick 事件的调用列表中。 Tick 事件的 InvocationList 将包含与您注册它的次数一样多的相同功能的条目。

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