Threading issue in C# using BackgroundWorker
Can some kind soul please explain why the following psudocode would not work. The problem is that the lock can never be aquired on the backgroundWorker (Monitor.TryEnter(bw)) when called from a new thread. If I call it from the main UI thread it works fine.
Thanks P
public class MyClass
{
private BackgroundWorker bw;
private void Button_Click(object sender, EventArgs e)
{
System.Threading.Thread t =
开发者_如何转开发 new System.Threading.Thread(new System.Threading.ThreadStart(DoStuff));
t.IsBackground = true;
t.Start();
}
private void DoStuff()
{
if (Monitor.TryEnter(bw))
{
WorkDetails wd = new WorkDetails('some stuff here');
bw.RunWorkerAsync(wd);
// etc... etc...
}
}
}
Are you missing a Monitor.Exit at the end of the if block. Without a Monitor.Exit, whichever thread first does a Monitor.TryEnter successfully will be the only thread that can enter again.
I'm not sure you are using the background worker (BGW) as it was intended
The idea behind it, usually, is that you don't create threads yourself but rather specify to the BGW what you want to be done asynchronously. so your code should look like:
private BackgroundWorker bw = new BackgroundWorker ();
ctor
{
bw.DoWork += (sender, e) => DoStuff();
}
private void Button_Click(object sender, EventArgs e)
{
bw.RunWorkerAsync();
}
For more information, see here
comments:
- As a rule of thumb, never lock on arbitrary objects (like you do on bw) but rather on objects whose sole purpose is locking. I recommend you read Jon Skeet's excellent multi threading guide
- You can add the BGW declaratively via the designer, saving yourself the instantiation and event hooking code
精彩评论