C# 带WPF/C问题的System.Threading.Timer

C# 带WPF/C问题的System.Threading.Timer,c#,wpf,C#,Wpf,我正在使用WPF/C#app,我编写了一个方法,每5秒钟执行一个另一个方法。 我使用System.Threading命名空间构建函数: prviate void TimerMetod() { var timer = new System.Threading.Timer( e => MyFunction(), null, TimeSpan.Zero, TimeSpan

我正在使用WPF/C#app,我编写了一个方法,每5秒钟执行一个另一个方法。 我使用System.Threading命名空间构建函数:

   prviate void TimerMetod()
    {
        var timer = new System.Threading.Timer(
            e => MyFunction(),
            null,
            TimeSpan.Zero,
            TimeSpan.FromSeconds(5));
    }

不幸的是,MyFunction只被调用了一次,我做错了什么?

不要对计时器使用局部变量,计时器将在TimerMetod结束后被释放,计时器必须是类成员

使用Dispatcher。对于WPF,这是比System.Threading.Timer更好的选项

与Dispatchermer不同,Timer在非UI线程上调用委托。当您的代码与UI交互时,可能会出现这个问题

public partial class MainWindow : Window
{
    private readonly DispatcherTimer _dispatcherTimer;
    private int _count;

    public MainWindow()
    {
        _dispatcherTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };
        _dispatcherTimer.Tick += OnTimer;

        InitializeComponent();
    }

    private void OnTimer(object source, EventArgs e)
    {
        _count++;
        text.Text = "Count:" + _count;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        _dispatcherTimer.Start();
    }
}
XAML代码

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Content="Start Timer" Click="Button_Click"></Button>
    <TextBlock Grid.Row="1" x:Name="text"></TextBlock>
    
</Grid>


您应该始终在WPF中使用Dispatcher,而不是System.Threading.Timer@Peregrine:“您应该始终在WPF中使用Dispatchermer”——这完全是错误的。在WPF中,对于UI线程计时,异步/等待现在是“最佳实践”。并且指出必须始终使用该或
Dispatchermer
是不正确的。在很多情况下,基于线程池的计时器是非常合适的,即使在WPF程序中也是如此?我说的对吗?@Xallares当你需要周期性地更新UI时,dispatchermer是正确的选择。请参阅编辑后的答案,了解您通常如何创建和启动它。