Cancel function does not work with backgroundWorker?

Ken Ekholm 211 Reputation points
2021-10-12T18:07:34.103+00:00

Cancel function does not work this code below. Can someone tell me what is wrong with this code?

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {

Array.ForEach(originalFiles, (originalFileLocation) =>
                {
                    FileInfo originalFile = new FileInfo(originalFileLocation);
                    FileInfo destFile = new FileInfo(originalFileLocation.Replace(sourcePath, destPath));
                    if (backgroundWorker1.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return;
                    }

                    if (destFile.Exists)
                    {
                       if (originalFile.Length != destFile.Length || originalFile.LastWriteTime != destFile.LastWriteTime)
                       {
                           originalFile.CopyTo(destFile.FullName, true);
                           count2++;
                           answer = count2 / count * 100;
                           answer = Math.Round(answer);
                           backgroundWorker1.ReportProgress(Decimal.ToInt32(answer));
                           textFile = "Copying file " + destFile.FullName.ToString();
                           logFile.Add(textFile);
                            countLines++;
                       }
                    }
                    else
                    {
                        Directory.CreateDirectory(destFile.DirectoryName);
                        originalFile.CopyTo(destFile.FullName, false);
                        count2++;
                        answer = count2 / count * 100;
                        answer = Math.Round(answer);
                        backgroundWorker1.ReportProgress(Decimal.ToInt32(answer));
                        textFile = "Copying file " + destFile.FullName.ToString();
                        logFile.Add(textFile);
                        countLines++;
                    }
                });
}

  private void buttonCancel_Click(object sender, EventArgs e)
        {
            backgroundWorker1.WorkerSupportsCancellation = true;
            backgroundWorker1.CancelAsync();
            buttonCancel.Enabled = false;
        }
Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
{count} votes

1 answer

Sort by: Most helpful
  1. Karen Payne MVP 35,596 Reputation points Volunteer Moderator
    2021-10-12T22:11:22.603+00:00

    The following code is in the following project.

    using System;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace CopyFileWhenDone.Classes
    {
        /// <summary>
        /// This would be to simulate a copying a file from another application
        /// </summary>
        public class FileOperations
        {
            public delegate void OnIterate(int sender);
            /// <summary>
            /// Provides current iteration value
            /// </summary>
            public static event OnIterate OnIterateEvent;
            /// <summary>
            /// 
            /// </summary>
            /// <param name="originalFile">File to copy</param>
            /// <param name="outputFile">File to copy too</param>
            /// <param name="delay">Milliseconds to delay to simulate a large file</param>
            /// <param name="token">cancellation token to permit cancelling this operation</param>
            /// <returns>Success</returns>
            /// <remarks>
            /// Exception handling is done at client level
            /// </remarks>
            public static async Task<bool> CopyFileTask(string originalFile, string outputFile, int delay, CancellationToken token)
            {
                int lineNumber = 0;
                using (var inputStream = File.OpenRead(originalFile))
                {
                    using (var inputReader = new StreamReader(inputStream))
                    {
                        using (var outputWriter = File.AppendText(outputFile))
                        {
                            var currentLine = await inputReader.ReadLineAsync();
    
                            await outputWriter.WriteLineAsync(currentLine);
    
                            if (delay > 0)
                            {
                                await Task.Delay(delay, token);
                            }
    
                            while (null != currentLine)
                            {
                                lineNumber += 1;
                                await outputWriter.WriteLineAsync(currentLine);
                                currentLine = await inputReader.ReadLineAsync();
                                OnIterateEvent?.Invoke(lineNumber);
                                if (token.IsCancellationRequested)
                                {
                                    token.ThrowIfCancellationRequested();
                                }
    
                                if (delay > 0)
                                {
                                    await Task.Delay(delay, token);
                                }
    
                            }
                        }
                    }
                }
    
                return true;
    
            }
        }
    }
    

    Form code

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    using CopyFileWhenDone.Classes;
    
    namespace CopyFileWhenDone
    {
        public partial class Form1 : Form
        {
            private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
    
            private string _inputFileName = "File1.txt";
            private string _outputFileName = "File2.txt";
            private int _currentLineNumber = 0;
            public Form1()
            {
                InitializeComponent();
                FileOperations.OnIterateEvent += FileOperations_OnIterateEvent;
            }
    
            private void FileOperations_OnIterateEvent(int sender)
            {
                _currentLineNumber = sender;
                Text = $"Current line: {sender}";
            }
    
            private async void CopyFileNoDelayButton_Click(object sender, EventArgs e)
            {
                ResetTokenSource();
                CheckFileExists();
    
                timer1.Enabled = true;
                listBox1.Items.Clear();
    
                try
                {
                    await FileOperations.CopyFileTask(_inputFileName, _outputFileName, 0, _cancellationTokenSource.Token);
                }
                catch (OperationCanceledException oce)
                {
                    MessageBox.Show("Operation cancelled");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    
    
                listBox1.Items.Add("Done");
                listBox1.SelectedIndex = listBox1.Items.Count - 1;
                timer1.Enabled = false;
                Text = "Code sample";
            }
    
            private void CheckFileExists()
            {
                if (File.Exists(_outputFileName))
                {
                    File.Delete(_outputFileName);
                }
            }
    
            private void ResetTokenSource()
            {
                if (!_cancellationTokenSource.IsCancellationRequested) return;
                _cancellationTokenSource.Dispose();
                _cancellationTokenSource = new CancellationTokenSource();
            }
    
            private async void CopyFileWithDelayButton_Click(object sender, EventArgs e)
            {
                ResetTokenSource();
                CheckFileExists();
    
                timer1.Enabled = true;
                listBox1.Items.Clear();
    
                try
                {
                    await FileOperations.CopyFileTask(_inputFileName, _outputFileName, numericTextBox1.AsInt, _cancellationTokenSource.Token);
                    listBox1.Items.Add($"Done with {_currentLineNumber} processed");
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                    timer1.Enabled = false;
                }
                catch (OperationCanceledException oce)
                {
                    timer1.Enabled = false;
                    listBox1.Items.Add($"Operation cancelled with {_currentLineNumber} processed");
    
                }
                catch (Exception ex)
                {
                    listBox1.Items.Add(ex.Message);
                    timer1.Enabled = false;
                }
    
                Text = "Code sample";
    
            }
            private async void timer1_Tick(object sender, EventArgs e)
            {
                if (File.Exists(_outputFileName))
                {
                    try
                    {
                        var result = await FileHelper.CanReadFile(_outputFileName) ? "Yes" : "No";
                        listBox1.Items.Add($"Ready: {result}");
                    }
                    catch (Exception exception)
                    {
                        listBox1.Items.Add(exception.Message);
                    }
                }
                else
                {
                    listBox1.Items.Add("Not found");
                }
    
                listBox1.SelectedIndex = listBox1.Items.Count - 1;
            }
    
            private void CancelButton_Click(object sender, EventArgs e)
            {
                _cancellationTokenSource.Cancel();
            }
        }
    }
    
    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.