0

I have modified Background worker private AbortableBackgroundWorker _worker;

public class AbortableBackgroundWorker : BackgroundWorker
{
    //Internal Thread
    private Thread _workerThread;

    protected override void OnDoWork(DoWorkEventArgs e)
    {
        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;
        }
    }
}

And have method which init BgWorker

private void BusyLoader(Action doWorkAction)
    {
        if (_worker == null)
        {
            _worker = new AbortableBackgroundWorker();
            _worker.WorkerReportsProgress = true;
            _worker.WorkerSupportsCancellation = true;
            _worker.DoWork += (sender, e) => _worker_DoWork(sender, e, doWorkAction);
            _worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
        }

        if (!_worker.IsBusy)
            _worker.RunWorkerAsync();
    }

private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            loadingPanel.StopSpin();
            _worker.Abort();
            _worker.Dispose();
        }

        private void _worker_DoWork(object sender, DoWorkEventArgs e, Action action)
        {
            loadingPanel.StartSpin();
            this.Dispatcher.Invoke(action);
        }

When I call method BusyLoader I want to pass there Action, which should be executed and at this time busy Indicator should be shown.

I have tried It. And it seems to work but only for first call of BusyLoader. Because _worker.DoWork has the same method, as I understand.

How can I manage to change _worker.DoWork method for every new call of BusyLoader ? Or it is bad approach to pass Action like that?

demo
  • 6,038
  • 19
  • 75
  • 149
  • Have you stepped through it? On the second use, `_worker` won't be null, will it? Setting it to null when completed would reset your state. As an aside, aborting threads is a bad idea (see [this question](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort/1560567#1560567), for example). And I can't see that `_workerThread` is ever set. And invoking the work on the UI thread defeats the point of this entirely - your spinner won't spin. – Charles Mager Jan 04 '16 at 16:37
  • 2
    Why don't you use Task instead of BackgroundWorker? Also, you could use a 'better' pattern with a progress bar visibility bound to some boolean in your model (or some visual state in XAML). – aybe Jan 04 '16 at 16:42
  • @Aybe, I have tried MVVM approach for my spinner, but it doesn't help... Everything works on UI thread so I don't see busy indicator – demo Jan 04 '16 at 17:06
  • _worker is not null on the second call so _worker_DoWork is not redefined. Try removing and adding. – paparazzo Jan 04 '16 at 18:18
  • @Frisbee, yep. this help in my case – demo Jan 04 '16 at 21:24

1 Answers1

0

You said it helped so will post comment as an answer

_worker is not null on the second call so _worker_DoWork is not redefined. Try removing and adding.

paparazzo
  • 44,497
  • 23
  • 105
  • 176