Windows形式应用的背景工作者

时间:2017-03-07 06:52:58

标签: c# winforms backgroundworker

我有以下星座:

MainForm.cs - >包括我的所有表单元素

Program.cs - >包括主要部分,它是一个xmlreader / writer来改变xml文件中的xml属性,可以大到4gb

所以这个小应用程序有效,但当然UI无法响应并冻结我想避免的,我也希望减少这个过程的持续时间

我从BtnClick事件开始调用我的xmlread / write方法:

    void BtnApplyChangesClick(object sender, EventArgs e)
    {
        Program p = Program.Instance;
        pbApplyChanges.Minimum = 0;
        pbApplyChanges.Step = 1;

        Cursor.Current = Cursors.WaitCursor;
        foreach(DataGridViewRow cr in dataGridView2.Rows)
        {
            pbApplyChanges.Maximum = dataGridView2.Rows.Count;
            p.changeElements(cr.Cells["Filename"].Value.ToString(), txtTenant.Text, txtDate.Text, txtEvtId2.Text);
            pbApplyChanges.PerformStep();
        }
        Cursor.Current = Cursors.Arrow;
        MessageBox.Show("Job done");
    }

在调用中,我使用Program.cs的单例实例和我的主要方法(changeElements)使用4个字符串参数,这些参数都来自表单中的信息! (我想这是一种不好的做法,但到​​目前为止它已经奏效了......)

当我尝试用backgroundWorker替换这个方法调用时(它本身就调用了方法)我失败了,因为方法调用甚至没有...我发现UI元素不能成为从BW线程访问,所以我想这也是我的方法调用无法工作的原因?!

那么我怎样才能使这个星座工作?我是否必须将所有4个字符串Params和类实例(Program.cs)传递给后台工作程序? BW甚至是这项工作的最佳工具吗?

2 个答案:

答案 0 :(得分:4)

通常,BackgroundWorker不应访问任何UI元素。在Winforms中,一个老建议是访问UI-Elements应该只是从UI-Thread发生。

您可以像这样使用Background-Worker:

private void Main(string[] args)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += Bw_DoWork;
    bw.RunWorkerCompleted += Bw_RunWorkerCompleted;

    //Parameter you need to work in Background-Thread for example your strings
    string[] param = new[] {"Text1", "Text2", "Text3", "Text4"};

    //Start work
    bw.RunWorkerAsync(param);
}

//Do your Background-Work
private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
    string[] param = e.Argument as string[];

    //Process your long running  task

    e.Result = null; //Set your Result of the long running task
}

//Taking your results
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //Apply your Results to your GUI-Elements
    myTextBox1.Text = e.Result.ToString();
}

背景 - 工作者顺便说一下老派的东西,所以如果你想学习新东西,请看看here并告诉自己有关TPL的信息。这样可以更好地处理异步。

事实上,我认为将4gb数据存储在XML文件中并不是很好。你觉得数据库?或者在许多XML文件中拆分XML文件?因此,您将能够以块的形式读取数据。

我希望这会对你有所帮助。

答案 1 :(得分:0)

我没有使用后台工作人员。我使用普通线程代替。试试这段代码:

public void ButtonDoWork_Click(eventArgs......) {
    DoWorkThread = new Thread(new ThreadStart(DoWork)); // Setup thread
    DoWorkThread.isBackground = true; // Its background so, we need to set background flag
    DoWorkThread.Start(); // Start the thread
}

private Thread DoWorkThread: // our Thread object
private void DoWork() { // This void contains action that will be performed by thread
    //TODO: Background processing. To update UI from another thread use Control.Invoke(...)
}

请注意,我没有测试过这段代码 - 我是从记忆中写下来的,而且已经很晚了,所以它无法正常工作。

您还可以阅读MSDN上的主题:)