Timer event is not triggered by pressing a button

I try to transfer Image filefor every 3 seconds from the source to the destination directory when I click the start button. The Stop button is designed to stop file transfer.

If I use the Start button a third time, the event does not fire; therefore files are not transferred.

The progress I made is below:

  • Start --- File Transfer; Press the STOP button // This also works.
  • Start --- File Transfer; Press the STOP button // It also works.
  • Start ----- The file is not transmitted, Event is not firing // It does not work!

What I did to solve the problem:

  • I set a breakpoint in the Tick event and the tick event does not fire.
  • I checked that SourceFiles.Count is bigger than TransferCount (SourceFiles.Count> TransferCount).
  • I noticed that during file transfer, if I click the Stop button during file transfer, this file remains untransmitted.

How can i fix this? Thank you in advance.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Threading;

namespace GridTest
{
    /// <summary>
    /// Interaction logic for Window3.xaml
    /// </summary>
    public partial class Window3 : Window
    {
        DispatcherTimer dispatcherTimer = new DispatcherTimer();
        private static List<string> SourceFiles = new List<string>();
        private static readonly string SourceDir = @"C:\TestFiles\Images\";
        private static readonly string DestinationDir = @"C:\Files\Images\3_5x5\";
        private static int TransferCount = 0;
        public Window3()
        {
            InitializeComponent();
            this.Loaded += Window3_Loaded;
        }
        void Window3_Loaded(object sender, RoutedEventArgs e)
        {
            dispatcherTimer.Interval = new TimeSpan(0, 0, 3);
            dispatcherTimer.Tick += dt_Tick;
        }
        void dt_Tick(object sender, EventArgs e)
        {
            if (TransferCount < SourceFiles.Count)
            {
                var fileName = System.IO.Path.GetFileName(SourceFiles[TransferCount]);
                var destFile = System.IO.Path.Combine(DestinationDir, fileName);
                System.IO.File.Copy(SourceFiles[TransferCount], destFile,true);
                System.IO.File.Delete(SourceFiles[TransferCount]);
                Console.WriteLine(string.Format("Total Files: {0} Number of files transferred: {1}", SourceFiles.Count, TransferCount + 1));
                TransferCount += 1;
            }
            else
            {
                Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", TransferCount + 1));
                (sender as DispatcherTimer).Stop();
                (sender as DispatcherTimer).Tick -= dt_Tick;
            }
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            if (!System.IO.Directory.Exists(DestinationDir))
            {
                System.IO.Directory.CreateDirectory(DestinationDir);
            }

            if (System.IO.Directory.Exists(SourceDir))
            {
                SourceFiles = Directory.GetFiles(SourceDir).ToList();
            }
        }

        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            dispatcherTimer.Stop();
        }
    }
}
+3
source share
3 answers

If you call Stop, your timer event should not fire until you set the IsEnabled property to true.
So I suggest a bit of refactoring

    void Window3_Loaded(object sender, RoutedEventArgs e)
    {
        LoadSourceFiles();
        StartTimer();
    }
    void StartTimer()
    {
        dispatcherTimer.Interval = new TimeSpan(0, 0, 3);
        dispatcherTimer.Tick += dt_Tick;
        dispatcherTimer.IsEnabled = true;
    }
    void LoadSourceFiles()
    {
        if (!System.IO.Directory.Exists(DestinationDir))
        {
            System.IO.Directory.CreateDirectory(DestinationDir);
        }

        if (System.IO.Directory.Exists(SourceDir))
        {
            SourceFiles = Directory.GetFiles(SourceDir).ToList();
        }
    }

and call this method every time you click the start button

    private void Start_Click(object sender, RoutedEventArgs e)
    {
        StartTimer();
    }

    private void Stop_Click(object sender, RoutedEventArgs e)
    {
        dispatcherTimer.IsEnabled = false;
    }

I also suggest resetting a global variable that keeps track of files transferred to zero when inside the Tick event you find that every file has been transferred (or disable the start button)

    ....
    else
    {
          Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", TransferCount + 1));
          (sender as DispatcherTimer).Stop();
          (sender as DispatcherTimer).Tick -= dt_Tick;
          TransferCount = 0;
    }

, , .

+2

, , . TaskEx.Delay async/await, ( .NET 4.0 vs2012 + Microsoft.Bcl.Async):

using System;
using System.Collections.Generic;
using System.Windows;
using System.Threading;
using System.Threading.Tasks;

namespace GridTest
{
    /// <summary>
    /// Interaction logic for Window3.xaml
    /// </summary>
    public partial class Window3 : Window
    {
        private static List<string> SourceFiles = new List<string>();
        private static readonly string SourceDir = @"C:\TestFiles\Images\";
        private static readonly string DestinationDir = @"C:\Files\Images\3_5x5\";
        public Window3()
        {
            InitializeComponent();
            this.Loaded += Window3_Loaded;
        }
        void Window3_Loaded(object sender, RoutedEventArgs e)
        {
        }

        async Task DoWorkAsync(CancellationToken token)
        {
            int transferCount;
            for (transferCount = 0; transferCount < SourceFiles.Count; transferCount++)
            {
                token.ThrowIfCancellationRequested();
                var fileName = System.IO.Path.GetFileName(SourceFiles[transferCount]);
                var destFile = System.IO.Path.Combine(DestinationDir, fileName);
                System.IO.File.Copy(SourceFiles[transferCount], destFile, true);
                System.IO.File.Delete(SourceFiles[transferCount]);
                Console.WriteLine(string.Format("Total Files: {0} Number of files transferred: {1}", SourceFiles.Count, transferCount + 1));
                transferCount += 1;

                await TaskEx.Delay(3000, token); // 3s delay
            }
            Console.WriteLine(string.Format("Total number of files transferred: {0}. Transfer Completed", transferCount + 1));
        }

        CancellationTokenSource _cts;
        Task _task;

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            if (_cts != null)
                _cts.Cancel();
            _cts = new CancellationTokenSource();
            _task = TaskEx.Run(() => DoWorkAsync(_cts.Token), _cts.Token);
        }

        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            if (_cts != null)
                _cts.Cancel();
        }
    }
}
+2

You never call Start on DispatchTimer.

Add this to the Window3_Loaded method:

dispatcherTimer.Start();
+1
source

All Articles