Cancel workflows in winforms

I have two lists, one is a master, the other is a child. When the index changes on the main, the child list is populated accordingly with entries related to the main. My problem arises when one wizard takes a long time to get all the records, and before he finishes receiving the records, the user clicks on another wizard, which takes less time to complete. What happens is that in the end, the wizard, which took more time, fills in the window for the list of children, even if the user is no longer on this host.

I use BackgroundWorker threads to populate.

bw_LoadAll.DoWork += new DoWorkEventHandler(bg_LoadAllWork); bw_LoadAll.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_LoadAllWorkCompleted); bw_LoadAll.WorkerSupportsCancellation = true; 

I subscribed to the SelectedIndexChanged event for the wizard, and I set the canceled to true:

 bw_LoadAll.CancelAsync(); 

Here is the code in the DoWork method:

 List<object> s = Repository.Instance().LoadAll(); if (!bw_LoadAll.CancellationPending) { e.Result = s; } else { e.Cancel = true; } 

But for some reason, the code for the filled employee continues to be called. Here is the working code:

 if (!e.Cancelled) { ddl.DataSource = e.Result; ddl.DisplayMember = "QuickName"; ddl.ValueMember = "ID"; } 

Is there anything else I have to do to cancel this thread from returning?

+4
source share
3 answers

Your bg_LoadAllWork method should be defined as:

 void bg_LoadAllWork(object sender, DoWorkEventArgs e) { // Do your work here... } 

Inside bg_LoadAllWork you need to check e.CancellationPending , and if it is true, set e.Cancel = true;

This last part is important - if you never install e.Cancel, then your "e.Cancelled" will never be true. Calling CancelAsync does not actually cancel anything - it's more like "Requesting background work to cancel itself" - you need to put the logic in place to trigger the cancellation.

+5
source

From CodeProject in your do_work function, you need to check the CancellationPending in the workflow, then set the DoWorkEventArgs.Cancel variable to true,

0
source

It has been a while since I used BackgroundWorker, but if I use memory when you call bw_LoadAll.CancelAsync , the actual abortion of your LoadAllWork method LoadAllWork if LoadAllWork does not check bw_LoadAll.CancelationPending .

Confirmed by http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx : "CancelAsync sends a request to complete the pending background operation and sets the CancellationPending property to true.

When you call CancelAsync, your working method has the ability to stop its execution and exit. Working code should periodically check the CancellationPending property to see if it is set to true.

So, in the SelectedIndexChanged event handler, when you call bw_LoadAll.CancelAsync() , it sets the value of bw_LoadAll.CancelationPending to true, but does not actually interrupt the LoadAllWork method. The slow bootloader will still complete.

0
source

Source: https://habr.com/ru/post/1286429/


All Articles