I'm using the ThreadPool to manage my threads. Separately from the UI thread I have a thread that does data retrieval and general work operations and I have a 3rd thread that updates the UI to reflect the status of requested operations.
See code below:
// ui thread
private void btnLoadClients_Click(object sender, EventArgs e)
{
// start thread 1
ThreadPool.QueueUserWorkItem(new Form1().LoadClientList);
}
// thread 1
private void LoadClientList(object state)
{
ThreadBusy = true;
ThreadAction = "Loading Clients...";
// start thread 2
ThreadPool.QueueUserWorkItem(new Form1().ShowProgress);
// get data
ClientController c = new ClientController();
List<Client> clients = c.GetClient();
foreach (Client item in clients)
{
cmbClientList.Items.Add(item.Name);
}
cmbClientList.Items.Insert(0, "Please select a client");
ThreadBusy = false;
}
// thread 2
private void ShowProgress(object state)
{
while (ThreadBusy)
{
foreach (string action in lstAction.Items)
{
// write the action that's being taken to the listbox
if (String.Compare(action, ThreadAction) != 0)
lstAction.Items.Add(ThreadAction);
}
}
}
Problem is that although ShowProgress is being hit when I set a breakpoint on it, execution isn't entering it really. The while (ThreadBusy)
line isn't getting hit ever.
Have I got anything wrong here?
ThreadPool.QueueUserWorkItem(new Form1().LoadClientList);
ThreadPool.QueueUserWorkItem(new Form1().ShowProgress);
You're creating new Form1
instances every time you start a background thread, every action you take in these methods will happen to these new, "unbounded" instances, not on the one interacting with the user.
If you want to perform background work in WinForms you can leverage the BackgroundWorker
class.
A really simple example:
public static class Program
{
public static void Main()
{
var backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true
backgroundWorker.Disposed += BackgroundWorker_Disposed;
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}
private static void BackgroundWorker_Disposed(object sender, EventArgs e)
{
// Cleanup after yourself.
}
private static void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Do your things in background.
}
private static void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Notify progress.
}
private static void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// The background task is complete ("successfully" is NOT implied).
}
}
ThreadBusy property that you set to true belongs to a different Form1 object. because the thread that runs ShowProgress executes on a new instance of Form1 and its ThreadBusy property is false always. Thats why it is not entering into the while loop.
Can you try this
ThreadPool.QueueUserWorkItem(this.ShowProgress);
instead of
ThreadPool.QueueUserWorkItem(new Form1().ShowProgress);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.