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

后台网站模板下载什么是长尾关键词举例

后台网站模板下载,什么是长尾关键词举例,花草网站有人做,php投资理财企业网站模板们已经知道,win32/MFC/WinForm/WPF 都依靠消息循环驱动,让程序跑起来。 这里就介绍 WPF 中是如何使用消息循环来驱动程序的。 1. 背景 只听说过 Dispatcher ,哪里来的消息循环? WPF 启动运行堆栈: > WpfApp1.…

们已经知道,win32/MFC/WinForm/WPF 都依靠消息循环驱动,让程序跑起来。

这里就介绍 WPF 中是如何使用消息循环来驱动程序的。
在这里插入图片描述

1. 背景

只听说过 Dispatcher ,哪里来的消息循环?

WPF 启动运行堆栈:

>	WpfApp1.exe!WpfApp1.App.OnStartup(System.Windows.StartupEventArgs e)17	C#PresentationFramework.dll!System.Windows.Application..ctor.AnonymousMethod__1_0(object unused)	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl()	mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)	mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)	mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)	WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state)	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()	WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()	WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)	WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)	WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)	WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)	WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam)	[本机到托管的转换]	[托管到本机的转换]	WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame)	PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)	PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)	WpfApp1.exe!WpfApp1.App.Main()	

可以发现 倒数第 4 行的PushFrameImpl 这个方法。
去看其源码,就发现了熟悉的消息循环 :

private void PushFrameImpl(DispatcherFrame frame)
{SynchronizationContext synchronizationContext = null;SynchronizationContext synchronizationContext2 = null;MSG msg = default(MSG);_frameDepth++;try{synchronizationContext = SynchronizationContext.Current;synchronizationContext2 = new DispatcherSynchronizationContext(this);SynchronizationContext.SetSynchronizationContext(synchronizationContext2);try{while (frame.Continue && GetMessage(ref msg, IntPtr.Zero, 0, 0)){TranslateAndDispatchMessage(ref msg);}if (_frameDepth == 1 && _hasShutdownStarted){ShutdownImpl();}}finally{SynchronizationContext.SetSynchronizationContext(synchronizationContext);}}finally{_frameDepth--;if (_frameDepth == 0){_exitAllFrames = false;}}
}

主要的 GetMessage 和 TranslateAndDispatchMessage 代码:

private bool GetMessage(ref MSG msg, IntPtr hwnd, int minMessage, int maxMessage)
{UnsafeNativeMethods.ITfMessagePump messagePump = GetMessagePump();try{if (messagePump == null){return UnsafeNativeMethods.GetMessageW(ref msg, new HandleRef(this, hwnd), minMessage, maxMessage);}messagePump.GetMessageW(ref msg, hwnd, minMessage, maxMessage, out var result);return result switch{-1 => throw new Win32Exception(), 0 => false, _ => true, };}finally{if (messagePump != null){Marshal.ReleaseComObject(messagePump);}}
}
private void TranslateAndDispatchMessage(ref MSG msg)
{bool flag = false;if (!ComponentDispatcher.RaiseThreadMessage(ref msg)){UnsafeNativeMethods.TranslateMessage(ref msg);UnsafeNativeMethods.DispatchMessage(ref msg);}
}

可以理解为:Dispatcher 对消息循环的操作进行了“封装” 。
那,Dispatcher 是谁?

2. Dispatchcer

大部分WPF对象,都是 DispatcherObject。这意味着,可以在 DispatcherObject 中(如 Window 中), 使用 this.Dispatchcer 获取到 Dispatchcer 。
在这里插入图片描述
一般我们会通过三种方式获取 Dispatchcer :

// App.Current.Dispatcher;(Application.Current.Dispatcher)
var dispatcher1 = App.Current.Dispatcher;// CurrentDispatcher;
var dispatcher2 = System.Windows.Threading.Dispatcher.CurrentDispatcher;// System.Windows.Threading.DispatcherObject.Dispatcher;
var dispatcher3 = this.Dispatcher;

可分为两类:

  • 当前线程的 Dispatcher:

    System.Windows.Threading.Dispatcher.CurrentDispatcher;

  • 创建对应对象的 Dispatcher:

    App.Current.Dispatcher;

    DispatcherObject.Dispatcher;

Dispatcher 和线程是什么关系?

  • Dispatcher 属于线程(与线程一一对应)。
  • 在单 UI 线程应用程序中,WPF的 UI 对象在获取 this.Dispatcher 属性时,不同对象取的都是同一个Dispatcher实例。(因为都是同一个 UI 线程创建的。)
  • 在默认的 WPF UI 线程中: App.Current.Dispatcher = DispatcherObject.Dispatcher

所有的线程(UI线程,普通线程)都有 Dispatcher 吗?
是的。

在所有线程中,调用 System.Windows.Threading.Dispatcher.CurrentDispatcher
都会得到一个属于这个线程的 Dispatcher 对象。(不用的时候不会创建)
所以:如果你想在一个后台线程中,使用 Dispatcher.CurrentDispatcher.Invoke
将操作封送到 UI 线程,是做不到的。因为这时候获取到的 Dispatcher 不是UI线程的 Dispatcher, 而是当前线程自己的 Dispatcher。

你最常用 Dispatcher 做什么?
跨线程访问UI
为什么不能直接跨线程访问UI?
在这里插入图片描述

3. Dispatcher 如何实现跨线程的调用

最常使用 Dispatcher 的创建就是,在后台线程更新 UI ,那 Dispatcher 是如何做到的呢。

当你调用

private void Foo()
{this.Width = 100;
}Application.Current.Dispatcher.Invoke(() =>
{Foo();
});

时,Dispatcher 究竟做了什么,把操作转移到 UI 线程上去了。
在这里插入图片描述

  1. 将调用的 Delegate 和优先级包装成一个DispatcherOperation放入Dispatcher维护的优先级队列当中,这个Queue是按 DispatcherPriority 排序的,总是高优先级的 DispatcherOperation 先被处理。
  2. 往当前线程的消息队列当中Post一个名为 MsgProcessQueue 的 Message。(这个消息是WPF自己定义的。)这个消息被Post到消息队列之前,还要设置 MSG.Handle,这个Handle就是Window 1#的Handle。指定Handle是为了在消息循环Dispatch消息的时候,指定哪个窗口的 WndProc 处理这个消息。
  3. 消息循环读取消息。
  4. 系统根据获取消息的Handle,发现跟Window1#的Handle相同,那么这个消息派发到Window1#的窗口过程,让其处理。
  5. 在窗口过程中,优先级队列当中取一个DispatcherOperation。
  6. 执行 DispatcherOperation.Invoke 方法,Invoke方法的核心就是调用 DispatcherOperation 构造时传入的Delegate,也就是 Dispatcher.BeginInvoke 传入的Delegate。最终这个Foo()方法就被执行了。

4 回顾

  • WPF 底层仍然靠信息循环来驱动。
  • Dispatcher 使用消息循环来实现跨进程的委托调用。
  • Dispatcher 属于线程,需要理解当前拿到的 Dispatcher 到底是哪个 Dispatcher 。
http://www.mmbaike.com/news/22486.html

相关文章:

  • 网站建设报价 东莞天津网站建设技术外包
  • 无版权的图片素材网站网站建设关键词排名
  • 做电影网站赚钱吗站长工具日本
  • 商业空间设计案例网站sem扫描电子显微镜
  • 订阅号怎么做微网站网络营销的手段包括
  • qq推广设置中心网站百度关键词seo排名优化
  • pc网页游戏网站武汉大学人民医院光谷院区
  • 个人可以做慈善网站吗seo裤子的关键词首页排名有哪些
  • h5购物网站模板关键词seo排名怎么选
  • 公司介绍简历模板网站seo优化的目的
  • 网站建设竞标成都营销型网站制作
  • 网站弹广告是什么样做的友情链接买卖代理
  • 建网站软件下载今日头条搜索优化怎么做
  • 英语机构网站建设方案网页设计培训
  • 长春网站排名优化百度怎么推广自己的作品
  • 网站保持排名搜索引擎营销的简称是
  • 做微博分析的网站网站开发月薪多少钱
  • 湖南衡阳网站建设国家卫生健康委
  • 番禺区网站建设哪里有seo优化方法
  • 新手怎么做网站推广搜索推广和信息流推广的区别
  • 做网站从设计到上线流程拼多多seo怎么优化
  • 陕西免费做网站公司口碑营销的定义
  • 安平县哪里做网站怎么做线上推广
  • 深圳专业的网站制作公司建设网站制作
  • 如何变更网站备案信息查询seo搜索优化费用
  • 做卖蜂蜜的网站计划书免费入驻的卖货平台有哪些
  • 佛山网站推广优化学会计哪个培训机构比较正规
  • 网站开发功能合同高端企业网站模板
  • 做网站需注意事项一站式营销推广
  • 邯郸网络营销推广平台seo关键词推广多少钱