BackgroundWorker奇怪的情况(程序没有响应)

本文关键字:响应 程序 情况 BackgroundWorker | 更新日期: 2023-09-27 17:51:03

我有一个后台工作者在我的Windows窗体应用程序。但是很奇怪,在_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时,没有问题。我不知道出了什么问题。

*编辑-完整代码:*

private void excelOperation(string sFile)
    {
        string str_merged = "";
        if (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";
            try
            {
                System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");//excel dil hatası için
                System.Globalization.CultureInfo dil;
                dil = new System.Globalization.CultureInfo("tr-TR"); //toUpper türkçe karakter hatası için
                Excel.Application xlApp;
                Excel.Workbook xlWorkBook;
                Excel.Worksheet xlWorkSheet;
                Excel.Range range;
                //Excel.Range mergeRange;
                ArrayList al = new ArrayList();
                string 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_Item(5);
                range = xlWorkSheet.UsedRange;
                string[,] excelArray = new string[range.Rows.Count, range.Columns.Count];
                int temp = range.Rows.Count - 1;
                Fcount = range.Rows.Count;

                temp[] t = new temp[range.Rows.Count];
                for (rCnt = 3; rCnt <= range.Rows.Count; rCnt++)
                {
                    for (cCount = 1; cCount <= range.Columns.Count; cCount++)
                    {
                        str = (range.Cells[rCnt, 15] as Excel.Range).Value2.ToString();
                        if (str == "TOPL. ADET") // satırlar arasında ki siyah başlıkları ayırmak için
                        {
                            rCnt = rCnt + 2;
                            str = "123";
                        }

                        //değerimiz #N/A yani null ise a string değerini atıyoruz 
                        if (str == "-2146826246")
                        {
                            str = "herhangi bi string";
                        }
                        if (IsNumeric(str)) // değerimiz null ise IsNumeric fonk na yollayıp doğruluyoruz
                        {
                            if ((range.Cells[rCnt, cCount] as Excel.Range).Value2 != null && (range.Cells[rCnt, cCount] as Excel.Range).Value2 != "")
                            {
                                str = (range.Cells[rCnt, cCount] as Excel.Range).Value2.ToString();
                                excelArray[rCnt - 1, cCount - 1] = str;
                                if (cCount == 1) { t[rCnt - 3].col_A = str; }
                                if (cCount == 4) { t[rCnt - 3].col_B = "00001"; }
                                if (cCount == 15) { t[rCnt - 3].col_C = str; }
                                if (cCount == 1) { str_merged = str; } //merged cell leri hafızada tutuyoruz
                            }
                            else // hafızadaki merged cell leri array imze atıyoruz
                            {
                                if (cCount == 1) { t[rCnt - 3].col_A = str_merged; }
                            }
                        }
                    }
                    string[] row = { t[rCnt - 3].col_A, t[rCnt - 3].col_B, t[rCnt - 3].col_C };
                    if (row[1] != null)
                    {
                        DataRow dr = dt.NewRow();
                        dr["malzeme"] = row[0];
                        dr["makine"] = row[1];
                        dr["miktar"] = row[2];
                        dt.Rows.Add(dr);
                    }
                    int percentage = 0;
                    percentage = rCnt * 100 / range.Rows.Count;
                    backgroundWorker1.ReportProgress(percentage);
                }
                bool hataVarMi = false;
                for (int i = 0; i < t.Length; i++)
                {
                    if (t[i].col_B == null || t[i].col_B == "")
                    {
                        continue;
                    }
                    DataSet ds = DBClass.Default.SelectCommand("select STOK_KODU from TBLSTSABIT where STOK_KODU = '" + t[i].col_B + "'");
                    if (ds.Tables[0].Rows.Count == 0)
                    {
                        hataVarMi = true;
                        textBox1.Text += t[i].col_B.ToString() + "'r'n";
                    }
                }
                if (hataVarMi)
                {
                    formHeight("buyuk");
                    groupBox1.Visible = true;
                    lblDurum.Text = "Mamul Kodu Hatası!";
                }
                else
                {
                    formHeight("kucuk");
                    btnNetsis.Enabled = true;
                    lblDurum.Text = "Veriler aktarıldı. Netsis'e kaydetme işlemi yapabilirsiniz. ";
                }
                btnDurdur.Visible = false;
                //xlApp.Application.Quit();
            }
            catch (Exception ex)
            {
                btnDurdur.Visible = false;
                MessageBox.Show(ex.ToString());
            }
        }
    }
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        try
        {
            dataGridView1.DataSource = dt;
        }
        catch (Exception ex)
        { 
        }
        return;
    }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        excelOperation(fileName);   
    }

BackgroundWorker奇怪的情况(程序没有响应)

不要在后台线程中填充DataGridView。填充DataTable对象或自定义对象集合。并将其作为DataSource分配给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;
}

这是一个类似问题的链接:

BackgroundWorker和COM互操作的问题

如果你手动创建一个线程并改变线程的公寓状态会怎样?

可能你正在挂起UI线程,锁定excelOperation方法中的一些UI控件。

我看到你写你正在填充一个网格或类似的东西。你是怎么做到的?您应该在一些后台变量上完成工作,当工作完成时,将其分配给网格的数据源或您需要的任何地方。

EDIT: just read lazyberezovsky answer