C# WPF/XAML应用程序的Windows API PostMessage到self的等价物?
在Windows应用程序开发的“旧时代”,使用PostMessage Windows API函数将消息发布到您自己的应用程序是将特定任务的处理从当前堆栈上下文中移出的好方法,同时保留在主线程上,从而避免尝试在另一个线程上执行主线程任务的细微差别(这当然会导致使用Invoke样式的方法将处理移回主线程,等等) 你所要做的就是:C# WPF/XAML应用程序的Windows API PostMessage到self的等价物?,c#,wpf,xaml,postmessage,delayed-execution,C#,Wpf,Xaml,Postmessage,Delayed Execution,在Windows应用程序开发的“旧时代”,使用PostMessage Windows API函数将消息发布到您自己的应用程序是将特定任务的处理从当前堆栈上下文中移出的好方法,同时保留在主线程上,从而避免尝试在另一个线程上执行主线程任务的细微差别(这当然会导致使用Invoke样式的方法将处理移回主线程,等等) 你所要做的就是: 创建数值大于WM_USER的自定义windows消息 使用PostMessage向您自己广播该消息 将处理程序添加到主对话框窗口,以处理自定义WM_*消息的消息并对其执行
- 创建数值大于WM_USER的自定义windows消息
- 使用PostMessage向您自己广播该消息
- 将处理程序添加到主对话框窗口,以处理自定义WM_*消息的消息并对其执行操作
请注意,尽管我不是专家,但我使用过C#的Task.Run()、TaskFactory.StartNew()、Control.BeginInvoke(),async/await等工具。正如我所说的,我正在寻找一些希望不需要创建新线程或任何其他不寻常的编码技巧的东西。好吧,我建议从一开始就不要进入这种情况 但也就是说,您可以将
异步void
与任务一起使用。Yield
:
async void DoSomethingAsync()
{
await Task.Yield();
// Code here will run directly off the message loop.
}
Task.Yield
将导致该方法立即返回,将该方法的其余部分排入消息循环的队列。async void
将导致异常直接抛出到消息循环
好的,你做到了。我刚刚发布了一个答案,里面有
任务。Yield
和async void
。Blech,现在我需要洗手了…“使用PostMessage…是移动特定任务处理的一个很好的方式”——我对其中“great”一词的用法表示怀疑。注意PostMessage()
的功能远不止于此;该场景中的效果与任何东西一样具有副作用。但是,是的,这是人们实现这一点的一种方式。Winforms等价物是Control.BeginInvoke()
(您已经使用过),WPF等价物是Dispatcher.BeginInvoke()
。不过,堆栈溢出确实不是此类API研究的最佳场所。首先要从API本身的文档开始。+1.PostMessage之所以有效,是因为您可以在等待某个内容时运行单独的消息泵,从而产生异步行为的错觉。当然,问题是,一旦您有了两个如果等待,则可能会出现死锁情况。Async/wait是一种C#机制,旨在通过确保异步代码在稍后恢复之前立即返回来替换此机制并防止死锁。如果从工作线程(而不是主线程)调用DoSomethingAsync(),则post-Yield()语句代码是否仍会在主线程上运行?“异步无效"是我心中的一根刺。我在你的网站上读了很多书,真的很明白为什么应该避免,特别是出于异常处理的原因。但在一些情况下,我发现自己在做一些真正痛苦的编码练习,试图避免它,并且总是放弃,无论如何都要这样做。事实上MS允许它用于事件德勒斯向我指出,尽管需要避免,但它有明确的用例。@RobertOschler:不。这只是一种跳转到当前上下文顶层的方法,因此如果在线程池线程上运行,wait
之后的代码将在不同的线程池线程上执行。很明显,我不会允许在我的线程中使用这种代码总有更好的方法,可能是重新设计的一部分。