C# cancelling DoWork of background worker

前端 未结 4 1704
春和景丽
春和景丽 2021-02-06 15:50

C# 2008

I am using the code below to login to a softphone. However, the login progess is a long process as there are many things that have to be initialized and checks t

相关标签:
4条回答
  • 2021-02-06 16:03

    There is one thing I don't need to call the this.bgwProcessLogin.CancelAsync(); as you can just set this e.Cancel = true;

    0 讨论(0)
  • 2021-02-06 16:10

    Within your DoWork() function you wrote .... Depending on how many tasks of the same structure are coming like the displayed two one, you could refactor this structure into an own method, giving the changing parts as parameters.

    Also this InvokeRequired if-else branch has doubled the output string. A little search here on stackoverflow or on the web should show you a pattern to accomplish this doubling.

    Evernything else looks quite good.

    0 讨论(0)
  • 2021-02-06 16:20

    There is maybe only one problem: if one of the operation in DoWork event handler would last for a long time. In this case you could abort your pending operation ONLY after that operation finished. If all operations in DoWork event can't last very long (for instance, no more than 5 seconds), its all OK, but if one of the operations can last for long time (5 minutes, for instance) in this case user have to wait until this operation finished.

    If DoWork contains long lasting operations you can use something like AbortableBackgroundWorker. Something like this:

    public class AbortableBackgroundWorker : BackgroundWorker
    {
        private Thread workerThread;
    
        protected override void OnDoWork(DoWorkEventArgs e)
        {
            workerThread = Thread.CurrentThread;
            try
            {
                base.OnDoWork(e);
            }
            catch (ThreadAbortException)
            {
                e.Cancel = true; //We must set Cancel property to true!
                Thread.ResetAbort(); //Prevents ThreadAbortException propagation
            }
        }
    
    
        public void Abort()
        {
            if (workerThread != null)
            {
                workerThread.Abort();
                workerThread = null;
            }
        }
    }
    

    In this case you can truly abort pending operations, but you also have some restrictions (for more information about aborting managed thread and some restrictions see Plumbing the Depths of the ThreadAbortException Using Rotor).

    P.S. I agree with Oliver that you should wrap InvokeRequired in more usable form.

    0 讨论(0)
  • 2021-02-06 16:26

    You are doing it the right way, I believe. You will find thread members that allow you to terminate or abort a thread, but you don't want to use them for something like this. It might look a little weird to have all of the "cancelled" checks in your code, but that allows you to control exactly when you exit your thread. If you were to "rudely" abort the worker thread, the thread has no control of when it exits, and there could be corrupted state.

    0 讨论(0)
提交回复
热议问题