From: Peter Duniho on
Tom P. wrote:
> I have an application that uses a BackgroundWorker to get a list of
> files. The user can navigate away from this to a different directory
> so there needs to be a way to interrupt the BackgroundWorker and
> restart with a different base path.

How is this different from the last time you asked this question? Why
are you not just continuing in the same message topic?

> The problem I have is if I check IsBusy

I already explained that you should not check IsBusy. There's no point
to doing that.

> and call CancelAsync() and
> wait for the backgroundWorker the wait loop is too tight for the
> BackgroundWorker to communicate with the UI thread

I also already explained that you should not have a loop where you wait
for the BackgroundWorker.

I also already explained that it's not a question of the loop being "too
tight". It's that the BackgroundWorker needs the thread that you are
tying up in order to complete.

> (unless I use
> DoEvents). If I don't check IsBusy, just call CancelAsync and restart
> the process the UI thread gets the cancel flag set after the second
> DoWork call and the BackgroundWorker is never able to start the second
> process.

I also already explained how to properly reuse a BackgroundWorker
instance, by not trying to restart it until your RunWorkerCompleted
event handler has been called.

I also already even posted a code example showing exactly how to do this.

Why are you starting this question all over again?

Pete
From: Peter Duniho on
Peter Duniho wrote:
> [...]
> Why are you starting this question all over again?

Ah. I think I see the problem. You are using Google's crappy news
service to read these newsgroups. They apparently didn't get my post.

Here's an archived copy of the thread (with my post) at a different site:
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-csharp/95856/BackgroundWorker-Cancel-only-works-with-DoEvents

Here's a link to the same thread, but on Microsoft's web site:
http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.dotnet.languages.csharp&tid=5cc6d728-03b2-44dc-bf8a-6cfa843e3207&cat=en_US_509906e4-26ee-47ae-bf53-9380538fa8a9&lang=en&cr=US&sloc=en-us&p=1#top

Hope that helps.

Pete
From: Patrice on
So with a listbox it would give something such as the code below. Main
points are :
- when an item is selected if the backgroundworker is not busy, it is
launched, if busy then a flag is set and it is cancelled
- when it completes, if the flag is set it is launch again from the
completed event
- the background work just keep the thread busy until the duration passed as
an argument is reached (2,4,8 or 16 allowing to play with more or less long
background works). Cancellation is checked every second...


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private bool runWhenCompleted;
public Form1()
{
InitializeComponent();

Object[] values = { 2, 4, 8, 16 };
listBox1.Items.AddRange(values);
listBox1.SelectedIndexChanged+=new
EventHandler(listBox1_SelectedIndexChanged);

backgroundWorker1.DoWork+=new
DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted+=new
RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}

private void listBox1_SelectedIndexChanged(object sender,EventArgs
e)
{
if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync(listBox1.SelectedItem);
else
{
runWhenCompleted = true;
backgroundWorker1.CancelAsync();
}
}
private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs
e)
{
const double UIDelay = 1.0;
BackgroundWorker bw = (BackgroundWorker) sender;
int Duration = (int)e.Argument;
Debug.WriteLine("DoWork : " + Duration.ToString());
Stopwatch workWatch = new Stopwatch();
Stopwatch UIWatch = new Stopwatch();
workWatch.Start();
UIWatch.Start();
while (workWatch.Elapsed.TotalSeconds<=Duration)
{
if (UIWatch.Elapsed.TotalSeconds>=UIDelay)
{
if (bw.CancellationPending)
{
e.Cancel = true;
break;
}
UIWatch.Restart(); // .NET 4.0 only does
Stop/Reset/Start...
}
}
e.Result = workWatch.Elapsed.TotalSeconds;
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
if (e.Cancelled) Debug.WriteLine("RunWorkerCompleted
(Cancelled)");
else Debug.WriteLine("RunWorkerCompleted
("+e.Result.ToString()+")");
if (runWhenCompleted)
{
runWhenCompleted = false;
bw.RunWorkerAsync(listBox1.SelectedItem);
}
}
}
}

--
Patrice

From: Tom P. on
On Apr 16, 8:15 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
> Peter Duniho wrote:
> > [...]
> > Why are you starting this question all over again?
>
> Ah.  I think I see the problem.  You are using Google's crappy news
> service to read these newsgroups.  They apparently didn't get my post.
>

Yeah, well... it's work. What am I gonna do. Thanks for understanding.


> Here's an archived copy of the thread (with my post) at a different site:http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-csharp/95856/Backg...
>
> Here's a link to the same thread, but on Microsoft's web site:http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg...
>
> Hope that helps.
>
> Pete

That it does! Basically double-up on the flags. I'll give it a try but
I'll tell you, more often than not I'm running into race conditions.
The Worker will get a cancel but RunWorkerCompleted won't get called
right away. Let's see what happens if I put the restart code in the
RunWorkerCompleted() event.

Give me a minute.
Tom P.
From: Tom P. on
On Apr 16, 8:15 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
> Peter Duniho wrote:
> > [...]
> > Why are you starting this question all over again?
>
> Ah.  I think I see the problem.  You are using Google's crappy news
> service to read these newsgroups.  They apparently didn't get my post.
>
> Here's an archived copy of the thread (with my post) at a different site:http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-csharp/95856/Backg...
>
> Here's a link to the same thread, but on Microsoft's web site:http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg...
>
> Hope that helps.
>
> Pete

HA! That's exactly what I wanted. Thanks Pete.

I look at IsBusy and if I need to I set a restartSetPath flag and then
CancelAsync().
In RunWorkerCompleted if this was Cancelled then I call DoSetPath from
there.

Works like a charm.

I knew there was a right way to do this.
Thanks again.
Tom P.