2017-03-07 101 views
-2

我有以下星座:后台工作

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

的Program.cs - >包含的主要部分,这是一个的XMLReader /作家在xml文件中改变xml属性,可以大到4GB

因此,这个小应用程序的作品,但当然UI得到反应和冻结,我想避免,我也希望减少这个过程的持续时间的方式

I st艺术我xmlread/write方法从BtnClick事件呼叫:

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字符串参数,可以说都考虑来自Form中的信息! (我想这是有点不好的做法,但它的工作到目前为止......)

当我试图用backgroundWorker替换此方法调用(本身使该方法调用然后)我失败,因为方法调用是不均匀做...我发现UI元素不能从BW线程访问,所以我想这也是我的方法调用不工作的原因?!

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

+0

不,你可以让class和params全局化。 (当然,如果你不需要多线程) – Sergio

回答

2

一般而言,BackgroundWorker不应该访问任何UI元素。在WinForms中,一个古老的建议是只需从UI线程中访问UI元素。

可以使用背景,工人是这样的:

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文件?所以你可以读取数据块。

我希望这可以帮助你。

+0

嗨sebi,这是有益的,但我的主要问题仍然存在,我迭代我的datagrid行(代表通常19-21文件目录中的xml文件)Afaiu的foreach应该在backgroundworkerDoWork但datagrid不能从那里访问...所以我还必须将datagrid对象传递给backgroundworker? – KlausKerner

+0

@KlausKerner你如何填写你的DataGrid?你应该有一个DataSource,例如一个DataTable。将此作为参数传递给您的BackgroundWorker。没有GUI元素。 – Sebi

+0

哦,当然,你说得对,它是一个可以使用的数据表,完全忘了它THX – KlausKerner

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上阅读关于Threads的内容:)

+0

thx为输入,到目前为止bgworker确实工作最后我也喜欢它很容易与进度条设置,所以它在我的小应用程序中有点意义...但我肯定会尝试多个线程,因为我觉得就像性能可能会好很多,特别是并行执行会有很大的意义,因为我必须一次处理约20 xml文件,范围从5-1500 MB;) - >这不是我的决定顺便说一句,我必须与这些工作xml如同它可能是蹩脚的... – KlausKerner