我有以下星座:
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甚至是这项工作的最佳工具吗?
答案 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上的主题:)