c# - 哪个线程在图形用户界面(如 Windows 窗体、WPF)中运行代码隐藏?
问题描述
我知道只有 GUI 线程可以更新 UI 组件,为了计算长时间运行的任务,我们必须使用线程池来完成艰苦的工作并创建一个延续任务来使用同步上下文任务调度程序更新 UI。
这是一个简单的 Windows 窗体应用程序
internal sealed class MyForm : Form
{
private readonly TaskScheduler m_syncContextTaskScheduler;
public MyForm()
{
m_syncContextTaskScheduler =
TaskScheduler.FromCurrentSynchronizationContext();
Text = "Synchronization Context Task Scheduler Demo";
}
protected override void OnMouseClick(MouseEventArgs e)
{
// This task uses the default task scheduler and executes on a thread pool thread
Task<Int32> t = Task.Run(...);
// This task uses the sync context task scheduler and execute on the GUI thread
t.ContinueWith(task => Text = "Result: " + task.Result,
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
m_syncContextTaskScheduler);
...
base.OnMouseClick(e);
}
}
我的问题很简单,哪个线程运行诸如OnMouseClick
方法之类的代码隐藏?执行此代码隐藏的是 GUI 线程本身,所以只涉及两个线程,一个 GUI 线程和一个工作线程?还是一个工作线程在后面运行这段代码,所以涉及一个 GUI 线程和两个工作线程?
解决方案
UI 生成事件的处理程序在 UI 线程中执行。因此,在您的代码OnMouseClick
中也将在 UI 线程中执行。将Task
在调度程序定义的线程上执行(通常是线程池的线程)。
从技术上讲,一些代码可以OnMouseClick
在非 UI 线程中调用您的代码,但这是不好的做法,标准的 WinForms/WPF 控件不会做这样的事情。
另请注意,线程池通常有多个任务线程。
推荐阅读
- caffe - 如何创建一个将未标记的“虚拟数据”作为输入的网络?
- docker - 在 Jenkins 中加速 NPM 构建
- android - 是否可以在 NativeScript 中使用 Cordova 插件?
- java - Intellij IDEA Tomcat git clone web 应用程序
- sql-server - tSQLt - AssertEqualsTable 如何工作?
- java - MongoDB服务器迁移导致查询性能变慢
- python - 读取 .csv 文件并根据特定列中的相等值连接值
- spring - Keycloak 和 Spring SAML:SigAlg 为空
- sql - ssrs 数据源 CSV 分号分隔,给出长列名
- yocto - yocto sunxi 机器名称