简体   繁体   English

强制在主线程上执行代码

[英]Forcing code execution on main thread

How can I force a section of code to be executed on my main thread? 如何强制在我的主线程上执行一段代码?

This is why I'd like to know: 这就是为什么我想知道:

I have a custom created message box that at times gets shown from a thread that is not the main thread. 我有一个自定义创建的消息框,有时从一个不是主线程的线程显示。 However, when the message box constructor is called I get an InvalidOperationException saying "The calling thread must be STA, because many UI components require this." 但是,当调用消息框构造函数时,我得到一个InvalidOperationException,说“调用线程必须是STA,因为许多UI组件都需要这个。” This makes sense, UI elements need to be handled on the main thread. 这是有道理的,需要在主线程上处理UI元素。

My MessageBox.ShowMessage(...) function is a static function that creates an instance of my custom message box and shows it. 我的MessageBox.ShowMessage(...)函数是一个静态函数,它创建我的自定义消息框的实例并显示它。 Is there a something I could put in ShowMessage that would force the message box to be created and shown on the main thread? 是否有一些东西可以放在ShowMessage中,它会强制创建消息框并显示在主线程上? Elsewhere in my code I use the Control.BeginInvoke to handle similar issues, but since it is a static function there is no already existing UI element for me to call BeginInvoke on. 在我的代码的其他地方,我使用Control.BeginInvoke来处理类似的问题,但由于它是一个静态函数,因此我没有现有的UI元素来调用BeginInvoke。

Do I have to call MessageBox.ShowMessage from with a Control.BeginInvoke? 我是否必须使用Control.BeginInvoke调用MessageBox.ShowMessage? I'd prefer the BeginInvoke (or some equivalent) to be called from within ShowMessage. 我更喜欢从ShowMessage中调用BeginInvoke(或一些等价物)。

There are a few options here: 这里有几个选项:

  • make the second thread STA (you can only do this for your own Thread - not for ThreadPool threads) - via .SetApartmentState(ApartmentState.STA); 制作第二个线程STA(您只能为自己的Thread执行此操作 - 不适用于ThreadPool线程) - 通过.SetApartmentState(ApartmentState.STA);
  • see if SynchronizationContext.Current is non-null; 看看SynchronizationContext.Current是否为非null; if so, use Send / Post 如果是这样,请使用Send / Post
  • pass the form/control in as an ISynchronizeInvoke instance (may not apply to WPF - I'm not 100% sure) 将表单/控件作为ISynchronizeInvoke实例传递(可能不适用于WPF - 我不是100%肯定)

Your thinking is right -- in order to get it to work properly, you're going to need to get it called from the main thread. 你的想法是正确的 - 为了让它正常工作,你需要从主线程中调用它。

The simplest way? 最简单的方法? When you start your main form, save a reference in a static variable that is visible to your ShowMessage() call. 当您启动主窗体时,将引用保存在ShowMessage()调用可见的静态变量中。 Then, your ShowMessage can do the standard: 然后,您的ShowMessage可以执行标准:

if(myForm.InvokeRequired)
{
     myForm.Invoke(() => ShowMessage(arg1,arg2,arg3));
     return;
}
.... other code here....

而不是直接显示消息框,只需向主线程发送一条消息,该消息指示主线程显示一个消息框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不阻塞主线程的情况下暂停 C# 代码执行? - How to Pause C# code execution without blocking main thread? 对话框如何在不阻塞主线程的情况下阻止代码执行? - How do dialogs prevent code execution without blocking the main thread? 强制某些代码始终在同一个线程上运行 - Forcing certain code to always run on the same thread 在主线程中运行代码 - Run code in main thread 只有当可选的主线程任务和工作线程完成时,我如何保证代码的执行? - How do I guarantee execution of code only if and when optional main thread task and worker threads are finished? 执行与主线程并行的线程 - Execute threads parallel to the execution of the main thread 强制执行方法 - Forcing the execution of a method 正确取消较长的“字符串”任务继续? 强制任务执行顺序和线程使用情况? - Cancelling a long “string” of Task continuations properly? Forcing Task execution order and thread usage? 如何在侦听/发送tcp客户端线程和主要执行之间进行同步? - How to sync between a listening/sending tcp client thread and the main execution? 如何将任务委派给主线程并等待其执行完成? - How to delegate a task to main thread and wait for it's execution to complete?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM