c# 进度条线程阻塞
时间: 2024-09-18 09:02:33 浏览: 32
在 C# 中,进度条通常是用于显示某个长时间运行的任务的完成程度。如果你在一个 UI 线程上更新进度条,而这个任务在另一个线程上运行,可能会导致线程阻塞,因为 UI 更新需要在主线程上安全地进行。如果直接在非 UI 线程上调用 Progress 属性(如 BackgroundWorker 的 Progress 或使用 Task 进度报告),这会使得界面冻结,用户体验变差。
为了避免这种情况,你可以采取以下几种策略:
1. 使用 `BackgroundWorker`:这个类提供了一种处理后台工作的机制,并通过 `ReportProgress` 方法在适当的时机更新进度条,同时保持 UI 线程的响应能力。
```csharp
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (sender, e) => { ...长时任务... };
worker.ProgressChanged += (sender, e) => {
progressBar.Value = e.ProgressPercentage;
};
worker.RunWorkerCompleted += (sender, e) => {
// 任务完成后处理
};
worker.RunWorkerAsync();
```
2. 利用 `Task` 和 `TaskCompletionSource`:你可以创建一个 Task 并使用 TPL 来管理进度更新。
```csharp
var tcs = new TaskCompletionSource<int>();
// 长时任务开始
new Thread(() => {
try {
int progress = 0;
while (/*检查任务进度*/) {
tcs.SetProgress(progress++);
// 执行任务操作...
}
tcs.SetResult(100); // 任务完成
} catch (Exception ex) {
tcs.SetException(ex);
}
}).Start();
Task.Run(() => {
var task = tcs.Task;
task.ContinueWith(t => {
if (t.IsFaulted)
throw t.Exception; // 如果发生异常
else
progressBar.Value = 100; // 设置进度条到100%并关闭
});
});
```
阅读全文