我有一个 backgroundworker,它进行一些计算并将进度结果报告为字符串。此字符串需要插入到 dataGridView 中。但是在插入值时,GUI 会卡住。
private void bckgrSorter_DoWork(object sender, DoWorkEventArgs e)
{
for (int i=0; i<1000; i++)
{
// doing some calculations
bckgrSorter.ReportProgress(i, someString);
}
}
private void bckgrSorter_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string results = (string)e.UserState;
dataGridView1.Rows.Add(results);
}
因此,即使我在后台线程上进行了所有繁重的计算,GUI 仍然卡住,因为 DataGridView。
编辑代码:
private void bckgrSorter_DoWork(object sender, DoWorkEventArgs e)
{
string[] folders = // some folders to get File List from
bckgrFileScanner.RunWorkerAsync(folders);
}
private void bckgrFileScanner_DoWork(object sender, DoWorkEventArgs e)
{
string[] folders = (string[])e.Argument;
foreach (string f in folders)
{
GetFileList(ref scannedFiles, f, bckgrFileScanner);
bckgrFileScanner.ReportProgress(1);
}
}
public void GetFileList(ref List<FileInfo> fList, string fPath, BackgroundWorker scanner)
{
DirectoryInfo di = new DirectoryInfo(fPath);
FileInfo[] fi = di.GetFiles();
foreach (FileInfo fiTemp in fi)
{
//ar ~$ saakas nevajadzīgie temp faili, tos izlaižam
if (fiTemp.Name.StartsWith("~$") == false)
{
fList.Add(fiTemp);
scanner.ReportProgress(0, fiTemp.Name);
}
}
DirectoryInfo[] dFolders = di.GetDirectories();
//katrai apakšmapei rekursīvi izsaucam šo funkciju
foreach (DirectoryInfo d in dFolders)
{
GetFileList(ref fList, d.FullName, scanner);
}
}
private void bckgrFileScanner_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage == 0)
{
filesDataGrid.Rows.Add(e.UserState);
}
else progressBar1.PerformStep();
}
最佳答案
在我看来,您需要对工作线程的结果进行批处理。也许您可以使 ProgressChanged 事件返回进度结果的集合或其他内容?或者最多每半秒使用最新数据触发一次事件。我怀疑问题是您只是想过快地添加数据。您需要在每个单元中完成更少的工作单元和更多的工作(一次添加很多行)。
巴巴尔是对的。像这样的东西可能会做你想做的事(我没有试过编译它):
public void GetFileList(ref List<FileInfo> fList, string fPath, BackgroundWorker scanner)
{
DirectoryInfo di = new DirectoryInfo(fPath);
FileInfo[] fi = di.GetFiles();
List<string> progressData = new List<string>();
foreach (FileInfo fiTemp in fi)
{
//ar ~$ saakas nevajadzigie temp faili, tos izlaižam
if (fiTemp.Name.StartsWith("~$") == false)
{
fList.Add(fiTemp);
progressData.Add(fiTemp.Name);
if (progressData.Count > 50){
scanner.ReportProgress(0, progressData.ToArray());
progressData.Clear();//You've just copied the data to an array and sent it to the GUI, clear the list and start counting up again
}
}
}
if (progressData.Count > 0){
scanner.ReportProgress(0, progressData.ToArray());
}
DirectoryInfo[] dFolders = di.GetDirectories();
//katrai apakšmapei rekursivi izsaucam šo funkciju
foreach (DirectoryInfo d in dFolders)
{
GetFileList(ref fList, d.FullName, scanner);
}
}
这不是一个很好的解决方案,但它是一个开始......
您还需要在回调中将 e.UserState 转换为字符串数组...
关于c# - 如何正确更新 DataGridView,这样 GUI 就不会卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5702090/