C#中UI线程的切换与后台线程的使用
文章速览
- UI线程切换
- 示例
- 后台线程使用
- 示例
- 两者对比
- 适用场景
- Application.Current.Dispatcher.Invoke
- Task.Factory.StartNew
- 执行同步性
- Application.Current.Dispatcher.Invoke
- Task.Factory.StartNew
一个赞,专属于你的足迹!
UI线程切换
在WPF应用程序中,UI元素只能由创建其的线程(通常UI线程)进行访问和修改。当我们从非UI线程尝试访问UI元素时,就需要通过使用【Application.Current.Dispacher.Invoke】将操作切换到UI线程。
示例
假设有一个按钮点击事件,在后台线程中进行一些处理后需要更新 UI 文本框的内容:
private void Button_Click(object sender, RoutedEventArgs e)
{Task.Factory.StartNew(() =>{// 后台线程中处理数据string result = LongRunningOperation();// 使用 Dispatcher.Invoke 更新 UIApplication.Current.Dispatcher.Invoke(() =>{textBox.Text = result;});});
}
private string LongRunningOperation()
{// 模拟耗时操作Thread.Sleep(3000);return "Result";
}
后台线程使用
当进行计算密集型任务或者耗时的操作(如数据处理、网络请求等),可以使用 【Task.Factory.StartNew】启动一个新线程来完成。
此处可以结合着同步、异步、并发来思考。
相关文章:
同步、异步、并发的区别
示例
如果只需要进行后台计算而不需要更新 UI:
private void Button_Click(object sender, RoutedEventArgs e)
{Task.Factory.StartNew(() =>{// 在后台线程中执行计算任务int result = CalculateResult();// 这里没有更新 UI 的操作});
}
private int CalculateResult()
{// 模拟计算任务Thread.Sleep(2000);return 42;
}
两者对比
适用场景
Application.Current.Dispatcher.Invoke
主要用于需要更新 UI 的情况。
例如,在多线程程序中,当一个后台线程完成了数据的计算或获取,需要将结果显示在 UI 上(如更新文本框、列表框等控件的内容),此时就需要使用 Application.Current.Dispatcher.Invoke 将更新 UI 的代码放到 UI 线程来执行。
Task.Factory.StartNew
更适用于需要并行处理任务的场景。比如,同时处理多个文件的读写操作,或者同时进行多个网络请求,或者执行一些复杂的计算任务,而这些任务不需要频繁地更新 UI。通过 Task.Factory.StartNew 可以有效地利用多核 CPU 的性能,提高程序的执行效率。
执行同步性
Application.Current.Dispatcher.Invoke
Invoke 方法是同步执行的。当调用 Invoke 时,调用线程(通常是后台线程)会一直等待直到 UI 线程完成指定的操作后才会继续执行后续的代码。这意味着如果 Invoke 中的操作比较耗时,调用线程会被阻塞。
Task.Factory.StartNew
一般用于启动异步任务。
任务一旦启动,它会在后台线程池中独立运行,调用线程(一般是 UI 线程)不会等待任务完成就继续执行后续代码。不过,可以通过一些同步机制(如 Wait、Result 等)来等待任务完成,但这不是默认的行为。