c# - Loading data to dataGridView freezes the window during loading, why threading does not work here? - Stack Overflow
- c - Solaris 10 make Error code 1 Fatal Error when trying to build python 2.7.16 - Stack Overflow 推荐度:
- javascript - How to dismiss a phonegap notification programmatically - Stack Overflow 推荐度:
- javascript - Get the JSON objects that are not present in another array - Stack Overflow 推荐度:
- javascript - VS 2015 Angular 2 import modules cannot be resolved - Stack Overflow 推荐度:
- javascript - Type 'undefined' is not assignable to type 'menuItemProps[]' - Stack Overflow 推荐度:
- 相关推荐
I have the following method that loads the data to DataGridView in a separate function. When I call the method in a button click, first two methods runs without hanging the windows since they dod not have any UI updates.
private async void btnSearch_Click(object sender, EventArgs e)
{
btnFolder.Enabled = false;
btnSearch.Enabled = false;
btnStop.Enabled = true;
try
{
var foldersTask = Task.Run(() => GetAccessibleDirectories(txtFolderPath.Text, chkSubFolders.Checked));
var folders = await foldersTask;
var BF = await Task.Run(() => getFolderdetails(folders));
await Task.Run(() => this.BeginInvoke(new Action(() => loadFoldersToGrid(BF)))); // Runs on UI thread
}
finally
{
btnFolder.Enabled = true;
btnSearch.Enabled = true;
btnStop.Enabled = false;
}
}
But when it starts running 'loadFoldersToGrid,' the window freezes (it backs to normal once it is loaded completely.). I don't understand it why.
private async void loadFoldersToGrid(BrowserFolders BF)
{
int i = 0;
long MBcon = 1048576;
long MB, Total = 0;
dgFolders.Rows.Clear();
dgFolders.Rows.Add(BF.folders.Count);
foreach (var rec in BF.folders)
{
dgFolders.Rows[i].Cells[0].Value = i;
dgFolders.Rows[i].Cells[1].Value = rec.folderPath;
dgFolders.Rows[i].Cells[2].Value = rec.fileCount;
long folderSize = GetFolderSize(rec.folderPath);
string megabytes = (folderSize / MBcon).ToString("F1");
dgFolders.Rows[i].Cells[3].Value = megabytes;
dgFolders.Rows[i].Cells[4].Value = rec.fileCreated.ToString("MM/dd/yyyy");
Total = Total + folderSize;
i += 1;
}
txtFolderCount.Text = BF.folders.Count.ToString();
txtSize.Text = string.Format("{0:N0} MB", Total / MBcon);
}
Any help ? tasks to not helping here.
I have the following method that loads the data to DataGridView in a separate function. When I call the method in a button click, first two methods runs without hanging the windows since they dod not have any UI updates.
private async void btnSearch_Click(object sender, EventArgs e)
{
btnFolder.Enabled = false;
btnSearch.Enabled = false;
btnStop.Enabled = true;
try
{
var foldersTask = Task.Run(() => GetAccessibleDirectories(txtFolderPath.Text, chkSubFolders.Checked));
var folders = await foldersTask;
var BF = await Task.Run(() => getFolderdetails(folders));
await Task.Run(() => this.BeginInvoke(new Action(() => loadFoldersToGrid(BF)))); // Runs on UI thread
}
finally
{
btnFolder.Enabled = true;
btnSearch.Enabled = true;
btnStop.Enabled = false;
}
}
But when it starts running 'loadFoldersToGrid,' the window freezes (it backs to normal once it is loaded completely.). I don't understand it why.
private async void loadFoldersToGrid(BrowserFolders BF)
{
int i = 0;
long MBcon = 1048576;
long MB, Total = 0;
dgFolders.Rows.Clear();
dgFolders.Rows.Add(BF.folders.Count);
foreach (var rec in BF.folders)
{
dgFolders.Rows[i].Cells[0].Value = i;
dgFolders.Rows[i].Cells[1].Value = rec.folderPath;
dgFolders.Rows[i].Cells[2].Value = rec.fileCount;
long folderSize = GetFolderSize(rec.folderPath);
string megabytes = (folderSize / MBcon).ToString("F1");
dgFolders.Rows[i].Cells[3].Value = megabytes;
dgFolders.Rows[i].Cells[4].Value = rec.fileCreated.ToString("MM/dd/yyyy");
Total = Total + folderSize;
i += 1;
}
txtFolderCount.Text = BF.folders.Count.ToString();
txtSize.Text = string.Format("{0:N0} MB", Total / MBcon);
}
Any help ? tasks to not helping here.
Share Improve this question asked 17 hours ago PCGPCG 2,2995 gold badges29 silver badges49 bronze badges 4 |1 Answer
Reset to default -1The issue arises because loadFoldersToGrid performs heavy operations and updates the UI within a foreach loop. UI updates in Windows Forms run on the main thread, and if you perform long-running computations or file I/O on the same thread, the UI will freeze until the task completes.
To fix this, you can split the heavy computation (GetFolderSize) and UI updates into separate threads. Use await and async to ensure the UI remains responsive.
Solution Here’s a refactored version of your code:
Updated btnSearch_Click
private async void btnSearch_Click(object sender, EventArgs e)
{
btnFolder.Enabled = false;
btnSearch.Enabled = false;
btnStop.Enabled = true;
try
{
// Get folders and folder details on background threads
var foldersTask = Task.Run(() => GetAccessibleDirectories(txtFolderPath.Text, chkSubFolders.Checked));
var folders = await foldersTask;
var BF = await Task.Run(() => getFolderdetails(folders));
// Update the DataGridView asynchronously
await LoadFoldersToGridAsync(BF);
}
finally
{
btnFolder.Enabled = true;
btnSearch.Enabled = true;
btnStop.Enabled = false;
}
}
Asynchronous LoadFoldersToGridAsync
private async Task LoadFoldersToGridAsync(BrowserFolders BF)
{
int i = 0;
long MBcon = 1048576;
long Total = 0;
// Clear and prepare the DataGridView rows on the UI thread
await Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
dgFolders.Rows.Clear();
dgFolders.Rows.Add(BF.folders.Count);
}));
});
foreach (var rec in BF.folders)
{
// Perform heavy computation (GetFolderSize) on a background thread
long folderSize = await Task.Run(() => GetFolderSize(rec.folderPath));
string megabytes = (folderSize / MBcon).ToString("F1");
Total += folderSize;
// Update the DataGridView on the UI thread
int currentIndex = i; // Capture the current index for the closure
await Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
dgFolders.Rows[currentIndex].Cells[0].Value = currentIndex;
dgFolders.Rows[currentIndex].Cells[1].Value = rec.folderPath;
dgFolders.Rows[currentIndex].Cells[2].Value = rec.fileCount;
dgFolders.Rows[currentIndex].Cells[3].Value = megabytes;
dgFolders.Rows[currentIndex].Cells[4].Value = rec.fileCreated.ToString("MM/dd/yyyy");
}));
});
i++;
}
// Update the total count and size on the UI thread
await Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
txtFolderCount.Text = BF.folders.Count.ToString();
txtSize.Text = string.Format("{0:N0} MB", Total / MBcon);
}));
});
}
Optional Optimization: Parallel Folder Processing
If you want faster execution, process the folders in parallel (e.g., with Parallel.ForEach or Task.WhenAll for asynchronous operations). Here's an example using Task.WhenAll:
private async Task LoadFoldersToGridAsync(BrowserFolders BF)
{
long MBcon = 1048576;
long Total = 0;
var tasks = BF.folders.Select(async (rec, index) =>
{
long folderSize = await Task.Run(() => GetFolderSize(rec.folderPath));
string megabytes = (folderSize / MBcon).ToString("F1");
await Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
dgFolders.Rows[index].Cells[0].Value = index;
dgFolders.Rows[index].Cells[1].Value = rec.folderPath;
dgFolders.Rows[index].Cells[2].Value = rec.fileCount;
dgFolders.Rows[index].Cells[3].Value = megabytes;
dgFolders.Rows[index].Cells[4].Value = rec.fileCreated.ToString("MM/dd/yyyy");
}));
});
Interlocked.Add(ref Total, folderSize);
});
await Task.WhenAll(tasks);
// Update total count and size on the UI thread
await Task.Run(() =>
{
this.BeginInvoke(new Action(() =>
{
txtFolderCount.Text = BF.folders.Count.ToString();
txtSize.Text = string.Format("{0:N0} MB", Total / MBcon);
}));
});
}
- 微软Office 365云服务真正“落地”中国了吗?
- [连载]巨头“心血之作”终失败(五):惠普TouchPad
- apache beam - Unable to Write processed Data to Parquet - Stack Overflow
- TypeScript Error (ts2345) when trying to collect property names in array - Stack Overflow
- wordpress - How do I write a plugin using jQuery to extend FooGallery plugin without "initialize failed" and &
- django - Multipe one-to-many relation between two models - Stack Overflow
- python - How to Get a Single Solution from a Physics-Informed Neural Network (PINN) for a PDE with Initial and Boundary Conditio
- Google Translate Widget Only Works in Chrome – Why? - Stack Overflow
- tracking - Add custom hand gestures in three.js - Stack Overflow
- html - Disable scrolling. Overflow:hidden not working - Stack Overflow
- java - How to write custom Spring Security PreAuthorize annotation - Stack Overflow
- logging - C++ spdlog: How to append output to last log message? - Stack Overflow
- Assigning Latitude and Longitude to Turtles in NetLogo from a GIS Map - Stack Overflow
- apple swift: is forKey:fileSize considered accessing non-public API? - Stack Overflow
- python - Multi-level list with each level number included - Stack Overflow
- c# - Microsoft.Extensions.Logging.LoggerFactory how to prevent an extra date to be added to the log filename - Stack Overflow
- java - jOOQ transaction does not work as expected - Stack Overflow
Datasource
such as aList<T>
or possibly a data table will speed up the process considerably since there is no redrawing required until you assign the data source....which the control is optimized for. – Ňɏssa Pøngjǣrdenlarp Commented 16 hours agotxtFolderPath.Text
andchkSubFolders.Checked
should be done on the UI thread. Your code reads them from aThreadPool
thread. – Theodor Zoulias Commented 9 hours ago