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