dis*_*kid 0 c# multithreading listbox backgroundworker winforms
我已经成功地完成了我BackgroundWorker的工作WinForm.它工作正常,但实际上它没有.从下面可以看出,我的形式有一个listbox以及一个Progress Bar.我正在使用它们来显示在一个文件中写一个收件人列表的进度for loop.我知道这个过程运行得太快了.每次写入一行时,都会listbox显示" 添加x个y收件人 "消息并删除其自身的最后一个条目,以便不会有太多文本.还有每个插入物,progress bar必须迈出一步.

当我在每次写入中添加1ms延迟时,程序工作正常Thread.Sleep(1).我的表单仍然可以在桌面上移动,表单看起来很正常.但是当我删除这个睡眠时(这是真实场景),表单会冻结,就好像我从未使用过并行BackgroundWorker开始一样.我怎样才能克服这个问题?
以下是我的BackgroundWorker DoWork()和ProgressChanged()事件:
做工作:
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当你经常调用ReportProgress()时,这是完全正常的.一个firehose问题,你要求UI线程做更多的工作然后它能够做.一旦它执行了一个委托目标,那么另一个目标可用,它永远无法赶上.它现在停止履行其他职责,响应输入和绘画窗口.它只是在派遣代表时燃烧100%的核心.调用队列在不受限制的情况下不断增长,但是在程序内存不足之前,用户会失去耐心,因此实际崩溃很少.
您需要通过不频繁地调用ReportProgress()来解决此问题.请记住,您只需要实现一个目标,保持用户的目光.这很容易,你的输出变成了一个难以理解的模糊,大约每秒20次更新.为您提供50倍的安全保证金.
| 归档时间: |
|
| 查看次数: |
782 次 |
| 最近记录: |