首页 > 编程语言 >线程同步 SynchronizationContext 在命令行程序中创建一个ui线程承载WPF运行

线程同步 SynchronizationContext 在命令行程序中创建一个ui线程承载WPF运行

时间:2024-03-20 15:22:23浏览次数:24  
标签:线程 Run uiContext SynchronizationContext ui UI Dispatcher

1、创建一个线程作为ui线程

ui线程要求必须是STA线程

        var t = new Thread(() => {


        });

        t.SetApartmentState(ApartmentState.STA);
        t.Start();

2、创建一个公共的SynchronizationContext作为同步的入口

在.NET框架中,Dispatcher是一个类,它负责接收和处理特定线程的消息队列,这通常在WPF应用程序的UI线程中使用。Dispatcher.CurrentDispatcher返回与当前线程关联的Dispatcher对象。

DispatcherSynchronizationContext是SynchronizationContext的一个实现,它使用Dispatcher来排队和执行工作项。这是在WPF中使用的,以确保只有在正确的线程(通常是UI线程)上才执行UI操作。

因此,这行代码:

uiContext = new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher);
创建了一个新的DispatcherSynchronizationContext实例,该实例与当前线程的Dispatcher关联。这样,当你使用uiContext.Post或uiContext.Send方法排队工作项时,它们将通过Dispatcher在正确的线程上执行。

然后,SynchronizationContext.SetSynchronizationContext(uiContext);将新创建的DispatcherSynchronizationContext设置为当前线程的同步上下文。这样,后续的异步操作可以使用这个同步上下文来排队工作项,以确保它们在正确的线程上执行。

总的来说,这些代码确保了在UI线程上执行UI操作,从而避免了多线程环境中的竞争条件和数据不一致问题。

 

            uiContext = new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher);
            SynchronizationContext.SetSynchronizationContext(uiContext);

 

3、开启消息循环

System.Windows.Threading.Dispatcher.Run() 是一个静态方法,它开始执行与当前线程关联的 Dispatcher 的事件循环。在 WPF 中,每个 UI 线程都有一个 Dispatcher,并且 Dispatcher.Run() 用于开始处理该 Dispatcher 的消息队列。

在一个典型的 WPF 应用程序中,当你启动应用程序时,主 UI 线程的 Dispatcher.Run() 方法会被自动调用,这使得主 UI 线程可以开始处理事件,例如用户输入、绘图命令等。

在你的情况下,你创建了一个新的 STA 线程并希望它能够处理 UI 事件。为了实现这一点,你需要在该线程上调用 Dispatcher.Run(),以开始处理与该线程关联的 Dispatcher 的消息队列。

注意,Dispatcher.Run() 是一个阻塞方法,这意味着它会一直运行,直到调度程序的队列被关闭(例如,通过调用 Dispatcher.BeginInvokeShutdown 或 Dispatcher.InvokeShutdown 方法)或应用程序终止。这就是为什么你通常会在线程的主循环中看到 Dispatcher.Run() 被调用,因为这意味着线程将一直存在,直到应用程序结束或调度程序队列被明确关闭。

System.Windows.Threading.Dispatcher.Run();

 

4、控制此线程的生命周期

        uiContext.Post(state => {

            Dispatcher.CurrentDispatcher.InvokeShutdown();
        },null);

 

 

全部代码

class Program 
{
    [STAThread]
    static void Main(string[] args) 
    {
        SynchronizationContext uiContext = null;

        var t = new Thread(() => {

            uiContext = new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher);
            SynchronizationContext.SetSynchronizationContext(uiContext);
            System.Windows.Threading.Dispatcher.Run();

            Console.WriteLine("2222");
        });

        t.SetApartmentState(ApartmentState.STA);
        t.Start();

        //while (t.IsAlive) 
        //{
        //    Thread.Sleep(100);
        //}

        // 在主线程上等待 UI 线程准备好
        while (uiContext == null)
        {
            Thread.Sleep(100);
        }

        uiContext.Post(state => 
        { 
            var winTest=new WinTest();
            winTest.Show();

        },null);

        uiContext.Post(state => {

            Dispatcher.CurrentDispatcher.InvokeShutdown();
        },null);




        while (true) 
        {
            Thread.Sleep(1000);
            Console.WriteLine(111);
        }

    }

}

 

标签:线程,Run,uiContext,SynchronizationContext,ui,UI,Dispatcher
From: https://www.cnblogs.com/xietianjiao/p/18085319

相关文章

  • 线程同步 SynchronizationContext 初识
    什么是SynchronizationContext?SynchronizationContext是.NET中的一个类,用于管理跨线程的同步操作。它提供了一种机制,使线程可以协调对共享资源的访问,从而防止并发问题。SynchronizationContext的工作原理SynchronizationContext与每个线程相关联。当线程执行时,它会使用关......
  • 100美金的Salesforce新产品Pro Suite, 能否成为中小企业的首选?
    毋庸置疑,Salesforce在其运营的几乎所有市场中都占据主导地位。Salesforce以23%的CRM市场份额遥遥领先,包括销售、服务、营销、商业和集成类别的应用程序。但通常情况下,Salesforce并不是中小型企业或初创企业的首选,企业会寻求更具成本效益的选择,例如Monday.com、HubSpot、Pipedriv......
  • redis自学(22)Redis是单线程还是多线程?
    Redis是单线程还是多线程?Redis到底是单线程还是多线程? 如果仅仅聊Redis的核心的业务处理部分(命令处理),答案是单线程 如果是聊整个Redis那么答案是对线程在Redis版本迭代过程中,在两个重要的时间节点上引入了多线程的支持:Redisv4.0:引入多线程异步处理一些耗时较长的任务,......
  • JAVA 线程池SingleThreadExecutor实践教程
    SingleThreadExecutor是一个单线程的Executor,它使用单个工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行。下面是使用SingleThreadExecutor的实践教程:步骤1:创建SingleThreadExecutor你可以使用Executors类提供的newSingleThreadExecutor方法来创......
  • JAVA线程池ScheduledThreadPool实践教程
    ScheduledThreadPool用于在给定的延迟之后,或者定期执行任务。以下是如何在Java中实践使用ScheduledThreadPool的步骤:步骤1:创建ScheduledThreadPool首先,使用Executors的newScheduledThreadPool方法来创建一个ScheduledThreadPool。参数是你想要在池中保持的线程数量。i......
  • webui自动化框架-playwright
    playwright中文文档Playwright为现代web应用提供了跨浏览器、快速且可靠的端到端的测试能力。|Playwright中文文档|Playwright中文网(bootcss.com)playwright安装pipinstallplaywrightplaywright-浏览器安装playwright的nohead模式需要在本地安装浏览器的内核pl......
  • 界面开发框架DevExpress XAF v24.1新版预告 - 跨平台应用UI(三)
    DevExpressXAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。XAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。本文中的内容概述了XAF跨平台.NET应用UI和DevExpress.NETApp、WebAPI服......
  • 【QT+QGIS跨平台编译】之八十三:【QGIS_Gui跨平台编译】—【错误处理:未定义类型QgsColo
    文章目录一、未定义类型QgsColorRamp二、错误处理一、未定义类型QgsColorRamp错误信息:二、错误处理第29行增加:#include"qgscolorramp.h"......
  • 【GUI界面软件】快手评论区采集:自动采集10000多条,含二级评论、展开评论!
    目录一、背景说明1.1效果演示1.2演示视频1.3软件说明二、代码讲解2.1爬虫采集模块2.2软件界面模块2.3日志模块三、获取源码及软件一、背景说明1.1效果演示您好!我是@马哥python说,一名10年程序猿。我用python开发了一个爬虫采集软件,可自动抓取快手评论数据,并且含二级评论......
  • JAVASE各模块结构图:面向对象、常用类、多线程、异常、IO流、集合、网络编程
    ......