Click here to Skip to main content
15,905,782 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am simply trying to abort thread by clicking a button to stop the process if user wanted instead of exiting the application
This is original code:
private void Abort_Click(object sender, EventArgs e)
        {
         //   thread1.Abort();
        }

        ///  Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
        private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e )
        {

            List<object> genericlist = e.Argument as List<object>;
            Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
            thread1.Start();
            thread1.Join(); //Waiting for thread to finish
        }


What I have tried:

I tried Abort() thread from button click event by moving thread field out of method, that way you can get access from your button click event, but it throws many errors
object sender;
     System.ComponentModel.DoWorkEventArgs e;
     List<object> genericlist = e.Argument as List<object>;
     Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));



     private void Abort_Click(object sender, EventArgs e)
     {
         thread1.Abort();
     }

     ///  Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
     private void backgroundCopy_DoWork( )
     {


         thread1.Start();
         thread1.Join(); //Waiting for thread to finish
     }

that's what i did but i get error under e and genericlist : a field initialize can not reference a non static field, method or property.
Posted
Updated 19-Dec-19 7:27am

1 solution

Aborting a thread is a very dangerous thing to do, and should be avoided at all costs.

You're using a BackgroundWorker, which already runs the work on a background thread. Starting another thread to do the work, and then freezing the initial background thread until your new thread has finished, will only decrease the performance of your code.

Forget the manual threading, and do the work in the DoWork event handler.

Set the WorkerSupportsCancellation property[^] to true. When you want to stop the worker, call the CancelAsync method[^]. Within your loop, check the CancellationPending property[^] to see if the work has been cancelled, and stop if it has.
C#
private void Abort_Click(object sender, EventArgs e)
{
    backgroundCopy.CancelAsync();
}

private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    List<object> genericlist = e.Argument as List<object>;
    if (genriclist is null || genericlist.Count < 2) throw new ArgumentException();
    
    string source = Convert.ToString(genericlist[0]);
    string destination = Convert.ToString(genericlist[1]);
    
    // Do your work here, periodically checking the CancellationPending flag:
    if (backgroundCopy.CancellationPending)
    {
        e.Cancel = true;
        return;
    }
}
 
Share this answer
 
Comments
Richard Deeming 19-Dec-19 14:06pm    
Why are you defining properties in your class instead of setting the properties on the BackgroundWorker?

Remove the lines:
public bool WorkerSupportsCancellation { get; set; }
[System.ComponentModel.Browsable(false)]
public bool CancellationPending { get; }

Select the BackgroundWorker in the designer, open its properties, and find the WorkerSupportsCancellation property. Set it to true.

Remove the lines:
Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
thread1.Start();
thread1.Join();

Either move the code from your Copy method into the backgroundCopy_DoWork method, or just call the Copy method directly, without starting another thread.

Within the code that performs the copy, periodically check the backgroundCopy.CancellationPending property and stop if it returns true.
Richard Deeming 19-Dec-19 14:20pm    
Because you don't have a control called cancelButton on your form.

Remove that method; it's not needed, since you're already cancelling the work from the Abort_Click handler.
AskalotLearnalot 19-Dec-19 14:30pm    
i am sorry i am still having issues after doing that.
Richard Deeming 19-Dec-19 14:52pm    
So you didn't read my answer at all?

Do not use a thread.

Check the backgroundCopy.CancellationPending periodically during the copy, and stop copying if it returns true.
AskalotLearnalot 20-Dec-19 9:33am    
Thank you for your time.
  private void Abort_Click(object sender, EventArgs e)
        {
            // Cancel the asynchronous operation.
            this.backgroundCopy.CancelAsync();
            // Disable the Cancel button.
            Abort.Enabled = false;
            cancel = !cancel;
        }


        ///  Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
        private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {

            //List<object> genericlist = e.Argument as List<object>;
            //Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
            //thread1.Start();
            //thread1.Join(); //Waiting for thread to finish
            List<object> genericlist = e.Argument as List<object>;
            if (genericlist is null || genericlist.Count < 2) throw new ArgumentException();

            string source = Convert.ToString(genericlist[0]);
            string destination = Convert.ToString(genericlist[1]);
            if (backgroundCopy.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

        }

I have this but I can't figure out how to call the Copy method like its done in:
//Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900