[英]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: 这里有几个选项:
Thread
- not for ThreadPool
threads) - via .SetApartmentState(ApartmentState.STA);
Thread
执行此操作 - 不适用于ThreadPool
线程) - 通过.SetApartmentState(ApartmentState.STA);
SynchronizationContext.Current
is non-null; SynchronizationContext.Current
是否为非null; if so, use Send
/ Post
Send
/ Post
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.