为什么我的多线程应用程序不应该做它应该做的事情?

时间:2015-12-14 14:13:29

标签: c# multithreading

我正在使用ThreadPool来管理我的线程。与UI线程分开,我有一个执行数据检索和一般工作操作的线程,我有一个第三个线程来更新UI以反映所请求操作的状态。

见下面的代码:

// 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);
        }                
    }
}

问题是虽然ShowProgress在我设置断点时被击中,但执行并没有真正进入。 while (ThreadBusy)行没有受到影响。

我这里有什么不对吗?

2 个答案:

答案 0 :(得分:5)

ThreadPool.QueueUserWorkItem(new Form1().LoadClientList);

ThreadPool.QueueUserWorkItem(new Form1().ShowProgress);

每次启动后台线程时,您都会创建新的Form1个实例,您在这些方法中采取的每个操作都会发生在这些新的&#34;无界&#34;实例,而不是与用户交互的实例。

如果您想在WinForms中执行后台工作,可以使用BackgroundWorker类。

一个非常简单的例子:

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).
    }
}

答案 1 :(得分:0)

您设置为true的ThreadBusy属性属于另一个Form1对象。因为运行ShowProgress的线程在Form1的新实例上执行,并且其ThreadBusy属性始终为false。这就是为什么它没有进入while循环。

你能试试吗

ThreadPool.QueueUserWorkItem(this.ShowProgress);

而不是

ThreadPool.QueueUserWorkItem(new Form1().ShowProgress);