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

标签 c# winforms backgroundworker

我的 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);   

    }

最佳答案

不要在后台线程中填充 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;
}

关于c# - BackgroundWorker 奇怪的情况(程序没有响应),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14218384/

相关文章:

c# - 当不抛出异常时,try/catch block 会影响性能吗?

c# - 如何使用C#GDI +图形和Windows窗体递归绘制希尔伯特曲线分形?

c# - 在 DoWork() 完成后将变量传递给 RunWorkerCompleted()

c# - 默认控制台窗口的文本颜色

c# - 您知道有可用的 F# 和 C# 互操作示例吗?

c# - 后台工作人员中的暂停/恢复循环

c# - .NET 4 中的自定义属性更改

c# - 从 ANSII 编码的文件中读取文本

c# - 自动隐藏菜单条

c# - 如何创建一个可以在设计时订阅另一个 WinForm 控件的 C# 属性?