c# – 从后台工作者更新GUI

问题的名称是:“从后台工作者更新GUI”,但正确的名称世界是:“从后台工作者更新GUI或从后台工作者报告多个变量(除了整数)”

请让我解释一下我的情况.在一个程序中,我有一个后台工作者来分析信息.作为这种分析的结果 – 形式GUI元素应该填充必要的数据.在GUI中我想更新

> 2 datagridviews
> 1个列表框
> 5个标签

据我所知 – 我只能通过后台工作者的ReportProgress()方法本地报告1个int值.

所以问题是 – 如何传递List<> (一些其他变量:string,int)通过ReportProgress()?基本上 – 我想用信息更新GUI,但“1整数”不会这样做.所以要么可以通过ReportProgress()传递多个变量,或者我可以使用BackgroundWorker内部的Invoke来更新GUI ..我个人不喜欢Invoke方法…你有什么看法?

这是我的代码(见评论):

private void button9_Click(object sender,EventArgs e) // start BW
    {
        bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        bw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;

        bw.RunWorkerAsync(10);
    }

    private void button10_Click(object sender,EventArgs e) // cancel BW
    {
        bw.CancelAsync();
    }

    private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs e)
    {
        int count = (int)e.Argument;
        for (int i = 1; i <= count; i++)
        {
            if (bw.CancellationPending)
            {
                e.Cancel = true;
                break;
            }

            List<List<string>> list_result = new List<List<string>>();
            list_result = Proccess();

            bw.ReportProgress(list_result.Count()); // right Now I can only return a single INT

            /////////// UPDATE GUI //////////////
            // change datagridview 1 based on "list_result" values
            // change datagridview 2
            // change listBox
            // change label 1
            // change label ..          

            Thread.Sleep(20000);
        }

        MessageBox.Show("Complete!");
        e.Result = sum;
    }

    private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
    {
        prog_count++;
        listBox1.Items.Add("Count: (" + prog_count.ToString() + "/20). Found: " + e.Progresspercentage.ToString() + ".");
    }

解决方法

调用ReportProgress时有一个UserState参数.
var list_result = new List<List<string>>();

new backgroundWorker1.ReportProgress(0,list_result);

参数类型是一个对象,因此您必须将其强制转换为您需要的类型:

void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
    var userState = (List<List<string>>)e.UserState;
}

这个棘手的问题是,如何确定您是否传回List,列表或单个字符串,数字等.您必须在ProgressChanged事件中测试每种可能性.

void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
    var myList = e.UserState as List<List<string>>;
    if (myList != null)
    {
        // use list
        return;
    }

    int myNumber;
    if (Int32.TryParse(e.UserState.ToString(),out myNumber))
    {
        // use number
        return;
    }

    var myString = e.UserState.ToString();
    // use string
}

或者,您可以创建一个包含所需所有值的类(或使用Tuple),在后台运行所有内容以填充该类,然后将其传递给RunWorkerCompleted事件,并从那里一次更新UI.

相关文章

原文地址:http://msdn.microsoft.com/en-us/magazine/cc163...
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采...
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下...
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Mic...
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么