-2

I am working with WPF/C# app and I wrote a method which execute an another method in every 5 seconds. I used System.Threading namespace to build a function:

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

Unfortunately MyFunction is called only once, what did i do wrong?

Xallares
  • 1
  • 5
  • You should always use a DispatcherTimer in WPF rather than System.Threading.Timer. https://stackoverflow.com/questions/2258830/dispatchertimer-vs-a-regular-timer-in-wpf-app-for-a-task-scheduler – Peregrine Jul 20 '20 at 22:04
  • @Peregrine: _"You should always use a DispatcherTimer in WPF"_ -- that's simply false. In WPF, for on-UI-thread timing, async/await is now "best practice". And it is _not_ correct to state that either that or `DispatcherTimer` must _always_ be used. There are many scenarios where the thread pool-based timers are perfectly appropriate, even in a WPF program. – Peter Duniho Jul 20 '20 at 22:23
  • 1
    But i assume, i should use DispatcherTimer? Am i right? – Xallares Jul 20 '20 at 22:37
  • 1
    @Xallares When you need to cyclically updated the UI, DispatcherTimer is the right choice. See the edited answer for how you would typically create and start it. – Clemens Jul 21 '20 at 06:17

1 Answers1

0

Don't use local variable for the timer, timer will be disposed after TimerMetod ends, timer must be a class member.

Use DispatcherTimer. For WPF this is better option than System.Threading.Timer

Threading.Timer calls delegate on non-UI thread unlike DispatcherTimer. This could be issue when you code interacts with 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 Code

<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>
Clemens
  • 123,504
  • 12
  • 155
  • 268
Dmitry Kolchev
  • 2,116
  • 14
  • 16