CountLessQ
CountLessQ

Reputation: 189

How to use thread.abort()

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.

Upvotes: 0

Views: 690

Answers (2)

CountLessQ
CountLessQ

Reputation: 189

In case you have to use threads, try this. Otherwise, try cancelAsync like in this link: https://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/

     // We will set this true to notify the worker threads return.
            private bool shouldAbort;
    // when hitting submit set:
    shouldAbort = false;
    void MethodThatDoesWork()
        {
                //we should stop if required
                if (shouldAbort)
                {
                    state.Stop();
                }
            //code
        }

we must be sure that all threads are terminated when the form is closed. so we add these controls.

   private void ItemsCopyer_FormClosing(object sender, FormClosingEventArgs e)
       {
         System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            shouldAbort = true;
            btnAbort.Enabled = false;
        }

Upvotes: -1

Eric Lippert
Eric Lippert

Reputation: 660493

How to use thread.abort()

You do not use Thread.Abort(), ever, unless you are doing an emergency shutdown of an entire application domain or process. You NEVER DO THIS. I hope that is very clear.

A few reasons you never do this are:

  1. There are many better ways to control cancellation of an asynchronous workflow than aborting it.
  2. Aborting a thread is not guaranteed to actually abort the thread. A thread which is actively resisting being aborted has ways to delay the abort indefinitely. It is not reliable, so don't use it.
  3. Most important: aborting a thread is guaranteed to maintain the correctness of the internal mechanisms used by the CLR to manage the thread. It is not guaranteed to maintain the correctness of your program! A thread abort can cause your program invariants to be violated in interesting ways which frequently lead to crashes. (Exercise: list the possible consequences of a thread abort happening during the construction of an object with a finalizer)

The right way to structure your program is to use a cooperative cancellation pattern, and represent your asynchronous work as a task that can be cancelled. The asynchronous work then periodically polls the token to see if it needs to cancel itself.

Moreover: if the asynchronous work is not processor bound, then the right solution is to not use a worker thread. Rather, use asynchronous IO and await the result. You would not hire a worker to stand by your mailbox and tell you when letters arrived; similarly, do not hire a worker to stand around waiting for an IO task to complete. Keep the asynchronous work on the main thread if it is not CPU bound, and your thread will keep servicing user requests while it waits.

I got an error a field initializer can not reference a non static field, method or property.

That's correct. A field initializer cannot use this in any way, including an implicit use inside the body of a lambda. The reason for this is because the field initializer runs before the body of the constructor runs, but it is the body of the constructor that initializes the fields of this. The language design is trying to save you from writing a nasty bug here.

You need to move your initialization logic into a constructor.

But more generally, if your program requirements are that you must asynchronously perform high-latency IO bound tasks that can be canceled by the user, then you have chosen the wrong mechanisms to correctly and safely achieve that goal.

I am near the end of the project therefor I don't want to make a lot of changes.

I'm sure you don't. The sooner you start fixing your architectural problems, the sooner you will have a correct, safe implementation.

I have a deadline

That's a management problem, not a technical one. My advice is that you explain the situation to your management. They deserve to know that the choices are to meet the deadline with an incorrectly structured and possibly unstable program, or to extend the deadline and restructure the program into a principled, correct, safe program that meets user requirements. Management should have the right to make an informed decision about the state of the project they're paying you for.

Upvotes: 13

Related Questions