【发布时间】:2014-08-22 09:22:08
【问题描述】:
我已经成功地让我的BackgroundWorker 在我的WinForm 上完成了它的工作。它工作正常,但实际上并非如此。如下所示,我的表单有一个listbox 和一个Progress Bar。我同时使用它们来显示在for loop 的文件中写入收件人列表的进度。我知道这个过程运行得太快了。每次写入一行时,listbox 都会显示一条“Adding x out of y recipients”消息,并删除其自身的最后一个条目,以免文本过多。同样,每次插入时,progress bar 都必须迈出一步。
当我使用Thread.Sleep(1) 在每次写入中添加 1 毫秒延迟时,程序运行良好。我的表单仍然可以在桌面上移动,并且表单看起来很正常。但是当我删除这个睡眠(这是真实的场景)时,表单会冻结,就好像我从来没有使用过并行的 BackgroundWorker 一样开始。我该如何克服这个问题?
这里分别是我的 BackgroundWorker 的 DoWork() 和 ProgressChanged() 事件:
DoWork:
private void backgroundWorkerConvertDatatableToFile_DoWork(object sender,
DoWorkEventArgs e)
{
try
{
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
Select(column => column.ColumnName);
sb.AppendLine(string.Join(GetDelimiter(campaignOutputFormat), columnNames));
backgroundWorkerConvertDatatableToFile.ReportProgress(-1,
dt.Rows.Count.ToString() + " recipients found.");
for (int i = 0; i < dt.Rows.Count; i++)
{
IEnumerable<string> fields = dt.Rows[i].ItemArray.Select(
field => field.ToString());
sb.AppendLine(string.Join(GetDelimiter(campaignOutputFormat), fields));
backgroundWorkerConvertDatatableToFile.ReportProgress(i,
string.Format("Adding {0} of {1}...", (i + 1).ToString(), dt.Rows.Count));
Thread.Sleep(1);
}
string outputFile = String.Format("{0}\\{1}.csv",
campaignOutputPath, campaignFileName);
backgroundWorkerConvertDatatableToFile.ReportProgress(0, "Writing to file..");
File.WriteAllText(outputFile, sb.ToString());
convertSuccess = true;
}
catch (Exception ex)
{
logger.Log(LogLevel.Error,
"FileCampaignRunner: ConvertDataTableToCSV", ex.Message);
convertSuccess = false;
}
if (convertSuccess)
{
backgroundWorkerConvertDatatableToFile.ReportProgress(100,
"Write to file successful!");
}
else
{
backgroundWorkerConvertDatatableToFile.ReportProgress(100,
"Error writing to file.");
}
}
ProgressChanged:
private void backgroundWorkerConvertDatatableToFile_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
switch (e.ProgressPercentage)
{
case -1:
listBoxMessages.Items.Add(e.UserState.ToString());
listBoxMessages.Items.Add("");
break;
case 100:
listBoxMessages.Items.RemoveAt(listBoxMessages.Items.Count - 1);
listBoxMessages.Items.Add(e.UserState.ToString());
break;
default:
listBoxMessages.Items.RemoveAt(listBoxMessages.Items.Count - 1);
listBoxMessages.Items.Add(string.Format(e.UserState.ToString()));
progressBar.PerformStep();
break;
}
}
【问题讨论】:
-
“冻结”是什么意思:您不能再使用它,或者它没有显示进度可能是因为它没有时间这样做?
-
@TaW 它变得没有响应。我无法拖动窗口,它变白了。
标签: c# multithreading winforms listbox backgroundworker