C# BackgroundWorker怪异案例(程序未响应)

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) {

我的Windows窗体应用程序中有一个backgroundworker。但奇怪的是,在_DoWork()完成后,程序没有响应,我什么也做不了

这就是我正在做的

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;
}