我有一个背景工作者问题 - 我是线程新手所以我试图尽可能轻松地完成这项任务。
我的主要问题是最终用户只有.NET 4.0,所以我不能使用await / async,并且被告知BGW对我正在使用的框架来说是最好的。
我有一个带有gif动画的“Please Wait”表单,我想在填充datagridview时加载它。我需要以某种方式做一个检查,以确保它已完成填充以关闭“请等待”,但我有点卡住如何实现这一点。
public void btnSearch_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
Application.DoEvents();
try
{
this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
int RowC = TestDataTableDataGridView.RowCount;
if (RowC == 0)
{
MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
}
catch (System.Exception exc)
{
MessageBox.Show
(
"Problem" +
exc.Message, "An error has occured", MessageBoxButtons.OK, MessageBoxIcon.Warning
);
}
finally
{
//pleaseWait.Close();
}
这是我将数据加载到DataGridView的按钮。到目前为止,这是我的DoWork活动
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
pleaseWait.ShowDialog();
}
由于交叉线程finally
将无效(因此当前注释掉)但我需要进行循环/检查以确定DataGridView是否已填充并且操作已完成然后关闭{{ 1}}。或者有些人如何强迫它跳转到DoWork
然后我可以在那里放一个RunWorkerCompleted
。
有什么建议吗?
答案 0 :(得分:1)
您必须在主ui主题中显示pleaseWait
对话框,而不是backgroundWorker1.DoWork
,并将其隐藏在RunWorkerCompleted
的{{1}}事件中。 this.TestDataTableAdapter.Fill是应该放在backgroundWorker1.DoWork中的部分,所以你的代码应该或多或少看起来像这样:
backgroundWorker1
当然,在此代码中您遇到了问题,因为public void btnSearch_Click(object sender, EventArgs e)
{
pleaseWait.ShowDialog();
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
}
catch (System.Exception exc)
{
//You can't show a messagebox here,as it is not in the UI thread
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pleaseWait.Close();
int RowC = TestDataTableDataGridView.RowCount;
if (RowC == 0)
{
MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
}
代码无法正常运行,因为您尝试访问某些TestDataTableAdapter.Fill
而您无法访问其他线程。
你有几个解决方案。您可以在调用backgroundworker之前使用一些变量来读取值,并访问此变量而不是TextBoxes
。或者您可以使用参数调用backgroundworker。
我建议您详细了解TextBoxes
,例如MSDN。或this question关于向BackGroundWorker
发送参数。