C# BackgroundWorker怪异案例(程序未响应)
我的Windows窗体应用程序中有一个backgroundworker。但奇怪的是,在_DoWork()完成后,程序没有响应,我什么也做不了 这就是我正在做的C# BackgroundWorker怪异案例(程序未响应),c#,winforms,backgroundworker,C#,Winforms,Backgroundworker,我的Windows窗体应用程序中有一个backgroundworker。但奇怪的是,在_DoWork()完成后,程序没有响应,我什么也做不了 这就是我正在做的 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { excelOperation(fileName); } private void button1_Click(object sender, EventArgs e) {
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
excelOperation(fileName);
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fDialog = new OpenFileDialog();
fDialog.Title = "Open Excel File";
fDialog.Filter = "Excel Files|*.xls;*.xlsx";
fDialog.InitialDirectory = @"C:\";
if (fDialog.ShowDialog() == DialogResult.OK)
{
fileName = fDialog.FileName;
backgroundWorker1.RunWorkerAsync();
}
}
excelOperation()是使用excel文件进行操作的东西
当我不使用_DoWork()时,我的意思是当我不使用BackgroundWorker时,没有问题。
我不知道怎么了
*编辑-整个代码:*
私有操作(字符串文件)
{
字符串str_merged=“”;
如果(sFile!=“”)
{
int rCnt=0;
int cCount=0;
dataGridView1.ColumnCount=3;
dataGridView1.Columns[0]。Name=“Makina Kodu”;
dataGridView1.Columns[1].Name=“Malzeme Kodu”;
dataGridView1.Columns[2].Name=“Üretilecek adet”;
尝试
{
System.Threading.Thread.CurrentThread.CurrentCulture=new System.Globalization.CultureInfo(“en-US”);//excel dil hatasıiçin
System.Globalization.CultureInfo dil;
dil=新体系.全球化.文化信息(tr tr)///toUpper türkçe karakter hatasıiçin
Excel.applicationxlapp;
Excel.工作簿;
Excel工作表;
范围;
//Excel.Range合并范围;
ArrayList al=新的ArrayList();
字符串str=“”;
xlApp=new Excel.ApplicationClass();
xlWorkBook=xlApp.Workbooks.Open(sFile,0,true,5,“,”,true,Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,“\t”,false,false,0,true,1,0);
xlWorkSheet=(Excel.Worksheet)xlWorkBook.Worksheets.get_项(5);
range=xlWorkSheet.UsedRange;
string[,]excelArray=新字符串[range.Rows.Count,range.Columns.Count];
int temp=range.Rows.Count-1;
Fcount=range.Rows.Count;
temp[]t=新的temp[range.Rows.Count];
对于(rCnt=3;rCnt您可能正在挂起UI线程,在excelOperation
方法中锁定一些UI控件
我看到你写了你正在填充一个网格或类似的东西。你是怎么做的?你应该在一些背景变量上完成这项工作,当工作完成时,将其分配到网格的数据源或任何你需要的地方
编辑:只需阅读lazyberezovsky的答案不要在后台线程中填充DataGridView
。填充DataTable
对象或自定义对象的集合。并在RunWorkerCompleted
事件处理程序中将其作为数据源
分配给DataGridView
样本:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fDialog = new OpenFileDialog();
//...
if (fDialog.ShowDialog() == DialogResult.OK)
backgroundWorker1.RunWorkerAsync(fDialog.FileName);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = (string)e.Argument;
// fill foos from excel
List<Foo> foos = excelOperation(fileName);
e.Result = foos;
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
dataGridView1.DataSource = (List<Foo>)e.Result;
}
private void按钮1\u单击(对象发送者,事件参数e)
{
OpenFileDialog fDialog=新建OpenFileDialog();
//...
如果(fDialog.ShowDialog()==DialogResult.OK)
backgroundWorker1.RunWorkerAsync(fDialog.FileName);
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
字符串文件名=(字符串)e.参数;
//从excel中填充foos
List foos=excelOperation(文件名);
e、 结果=foos;
}
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,
RunWorkerCompletedEventArgs(e)
{
dataGridView1.DataSource=(List)e.Result;
}
这里有一个类似问题的链接:
如果手动创建线程并更改线程的单元状态会怎么样?也许这会有所帮助。您在方法excelOperation中做了什么?主要步骤是,您是否对UI元素做了任何操作?如果锁定主线程和后台线程之间共享的某些资源,您可以挂起UI线程读取excel文件并填充正在初始化datagridview。是否正在使用COM互操作?可能会在某个地方出现交叉线程异常,如第一个答案所示……如果不查看所有代码,很难说……也可能会出现无休止的循环,但您会让所有人都在黑暗中看到不完整的代码。完全按照您所说的做了尝试,但没有任何更改。@Mtok如果您愿意,会发生什么注释数据源分配(但集合创建将保留在DoWork处理程序中)?您是否在后台线程中使用了其他共享资源?我正在连接SQL Server。可能与此有关吗?@Mtok在您看到datagrid中的结果之前可能会导致延迟,但如果您在后台线程中连接SQL Server,则不应冻结您的数据UI@Mtok在后台线程中仍然有很多与UI相关的代码(向gridview添加列,更新文本框和标签)-您应该删除所有这些代码。
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fDialog = new OpenFileDialog();
//...
if (fDialog.ShowDialog() == DialogResult.OK)
backgroundWorker1.RunWorkerAsync(fDialog.FileName);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = (string)e.Argument;
// fill foos from excel
List<Foo> foos = excelOperation(fileName);
e.Result = foos;
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
dataGridView1.DataSource = (List<Foo>)e.Result;
}