当前位置: 首页 > news >正文

WPF STA线程

在Thread线程中创建窗口并显示

private void btn_Click(object sender, RoutedEventArgs e)
{var thread = new Thread(() => {var win = new Window() {Title="另一个线程创建的窗口",Width=400,Height=300,};win.Show();});thread.Start();
}

运行代码后你会得到这样的错误:

“System.InvalidOperationException”类型的未经处理的异常在 PresentationCore.dll 中发生 
调用线程必须为 STA,因为许多 UI 组件都需要。

咨询了一下AI、COM组件和UI控件都需要在STA(Single-Threaded Apartment)线程模型上工作,为了:保证同一时间只有一个线程可以操作UI。
Thread类提供了SetApartmentState方法,对线程单元进行设置。解决上面报错的方式如下:

private void btn_Click(object sender, RoutedEventArgs e)
{var thread = new Thread(() => {var win = new Window() {Title="另一个线程创建的窗口",Width=400,Height=300,};win.Show();});thread.SetApartmentState(ApartmentState.STA);//设置线程为STA线程thread.Start();
}

为什么窗口闪烁一下就没了?答:Window的Show方法执行完毕了。
那为什么,一个WPF程序的MainWindow不会退出?因为把MainWindow,Show出来的方法是这样做的:

internal int RunInternal(Window window)
{//省略了很多代码base.Dispatcher.BeginInvoke(DispatcherPriority.Send, (DispatcherOperationCallback)delegate(object obj){Window window2 = obj as Window;window2.Show();return (object)null;}, window);//省略了很多代码if (!BrowserInteropHelper.IsBrowserHosted){RunDispatcher(null);//这一行是关键}return _exitCode;
}private object RunDispatcher(object ignore)
{if (_ownDispatcherStarted){throw new InvalidOperationException(System.Windows.SR.Get("ApplicationAlreadyRunning"));}_ownDispatcherStarted = true;Dispatcher.Run();//调用这个方法就可以使方法退不出去了return null;
}

所以,我们也模仿他,整一个消息循环。

private void btn_Click(object sender, RoutedEventArgs e)
{var thread = new Thread(() =>{var win = new Window(){Title = "另一个线程创建的窗口",Width = 400,Height = 300,};win.Show();Dispatcher.Run();//这一行保证了窗口不关闭});thread.SetApartmentState(ApartmentState.STA);thread.Start();
}

这就完事儿了么?当你关闭窗口后,其实 Dispatcher.Run() 这行还是在消息循环中....,你可以在vs调试其中点击暂停,通过查看并行堆栈,可以看到子窗口虽然已经关闭但是,Dispatcher.Run()可没有执行完成。
那么,如何退出消息循环?答:在window的closed事件中调用,Dispatcher.ExitAllFrames();下面给出较为完善的版本:

private void btn_Click(object sender, RoutedEventArgs e)
{var thread = new Thread(() =>{var win = new Window(){Title = "另一个线程创建的窗口",Width = 400,Height = 300,};win.Closed += Win_Closed;win.Show();Dispatcher.Run();//这一行保证了窗口不关闭});thread.SetApartmentState(ApartmentState.STA);thread.Start();
}private void Win_Closed(object sender, EventArgs e)
{System.Windows.Threading.Dispatcher.ExitAllFrames();
}

如此,我们便成功地在另一个线程创建了一个窗口。
参考:
【WPF】在新线程上打开窗口
为什么 WPF 的 Main 方法需要标记 STAThread

http://www.jsqmd.com/news/444195/

相关文章:

  • 2026 商务全自动商用咖啡机选购指南推荐,从入门到高配实用选型指南 - 品牌2026
  • 厂家提醒:选购全自动总磷总氮分析仪,除了参数还应关注什么? - 品牌推荐大师1
  • Git 忽略本地修改 不再出现在本地改变
  • 【往届已完成EI检索】第二届物理学与量子计算国际学术会议(ICPQC 2026)
  • 堵车不堵心,健力宝多品类为春节返程旅客“补水续航” - 速递信息
  • 【ACM出版-EI稳定检索】第二届健康大数据国际学术会议(HBD 2026)
  • 2026年儿童羽绒服十大名牌排名,宝妈宝爸闭眼入! - 品牌测评鉴赏家
  • 2026年绝缘陶瓷管/陶瓷支架厂家权威推荐:宜兴胜达耐火陶瓷,氧化铝/滑石瓷/堇青石全系绝缘陶瓷供应商 - 品牌推荐官
  • 2026线下买童装去哪家?宝妈实测! - 品牌测评鉴赏家
  • 2026三八女神节NMN抗衰榜:NMN品牌怎么选? - 速递信息
  • 论文降AI率省钱攻略:如何用最少的钱达到最好的降AI效果 - 我要发一区
  • 2026 全自动商用咖啡机哪家技术强?商用高性价比品牌推荐 - 品牌2026
  • 2026酒精厌氧絮状菌种直销:揭秘行业优质厂家排行,酒精厌氧絮状菌种选哪家深度剖析助力明智之选 - 品牌推荐师
  • 降AI率不只靠工具!手动+工具组合降AI的进阶技巧 - 我要发一区
  • 【业务架构】用蜘蛛表格搭建销售管理系统:表结构设计+自动化规则详解 - 蜘蛛小助理
  • 2026智慧环卫管理平台推荐:郑州森鹏物联网,提供环卫一体化综合管理解决方案 - 品牌推荐官
  • 2026年重庆搬家搬厂厂家榜单 专业团队护航 适配家庭与个性化需求 解决各类搬迁核心痛点 - 深度智识库
  • 2026年2月山东干选机/智能干选设备/煤矸分选设备/大块煤矸分选设备/智能干选系统/干选设备厂家专业推荐:口碑与技术双优榜单 - 2026年企业推荐榜
  • 2026年碳酸钙系列原料推荐:石家庄驰霖矿产品,纳米/重质/活性/造纸用/超细碳酸钙全系供应 - 品牌推荐官
  • 2026年用户推荐:这些精密倒角机厂家值得信赖,全自动倒角机/双头倒角机/数控倒角机/圆棒倒角机,精密倒角机厂家怎么选择 - 品牌推荐师
  • 2026年地面/混凝土/瓷砖/抹灰/墙面空鼓治理推荐:浙江耐威德化工科技专业方案 - 品牌推荐官
  • phpStudy v8.1 离线版一键安装包(小皮面板)
  • 2026优质腾讯企业邮箱代理商推荐,正规渠道一站式服务指南 - 品牌2026
  • 宝妈宝爸必看!2026线下童装宝藏店铺大揭秘 - 品牌测评鉴赏家
  • 宝妈必藏|2026优质儿童鞋服品牌盘点,帮你轻松搞定娃的穿搭选品 - 品牌测评鉴赏家
  • 猫眼电影内容可视化与智能分析平台 | Python Flask框架 Echarts 推荐算法 爬虫 大数据 毕业设计源码
  • 2026年超大型/危险品仓库/石油化工/制药厂/变电站防爆门窗推荐:无锡志诚特种门窗 - 品牌推荐官
  • 2026年混凝土搅拌设备推荐:郑州市振中机械有限公司,全型号搅拌机/搅拌站设备一站式供应 - 品牌推荐官
  • 2026年电永磁设备推荐:株洲悍威磁电科技,吊具/吸盘/夹具/快速换模等全系产品解析 - 品牌推荐官
  • 2026旋转门厂家实力推荐:上海旋迈自动门设备有限公司,写字楼/酒店/政府机关/商场旋转门全系解决方案 - 品牌推荐官