当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么我的多线程应用程序不应该做它应该做的事情?》经验,为你挑选了1个好方法。

我正在使用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 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)条线不会受到打击.

我这里有什么不对吗?



1> Albireo..:
ThreadPool.QueueUserWorkItem(new Form1().LoadClientList);

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

Form1每次启动后台线程时都会创建新实例,这些方法中的每个操作都会发生在这些新的"无界"实例上,而不是与用户交互的实例.

如果要在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).
    }
}


我认为`BackgroundWorker`也有点过时了.我个人更喜欢`Task.Run(带有[`IProgress `](https://msdn.microsoft.com/en-us/library/hh138298(v = vs.110).aspx)参数传入给方法.如果这样做一个[`新进展()`](https://msdn.microsoft.com/en-us/library/hh193692(v = vs.110)的.aspx)上的用户界面在后台线程上执行[`IProgress.Report(无论)`](https://msdn.microsoft.com/en-us/library/hh137797(v = vs.110).aspx)的线程进行UI编组.
推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有