将 C# MethodInvoker.Invoke() 用于 GUI 应用程序...这样好吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/782274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using C# MethodInvoker.Invoke() for a GUI app... is this good?
提问by Stécy
Using C# 2.0 and the MethodInvoker delegate, I have a GUI application receiving some event from either the GUI thread or from a worker thread.
使用 C# 2.0 和 MethodInvoker 委托,我有一个 GUI 应用程序从 GUI 线程或工作线程接收一些事件。
I use the following pattern for handling the event in the form:
我使用以下模式处理表单中的事件:
private void SomeEventHandler(object sender, EventArgs e)
{
MethodInvoker method = delegate
{
uiSomeTextBox.Text = "some text";
};
if (InvokeRequired)
BeginInvoke(method);
else
method.Invoke();
}
By using this pattern I do not duplicate the actual UI code but what I'm not sure about is if this method is good.
通过使用这种模式,我不会复制实际的 UI 代码,但我不确定这种方法是否好。
In particular, the line
特别是,该行
method.Invoke()
does it use another thread for invoking or does it translate somewhat to a direct call to the method on the GUI thread?
它是使用另一个线程进行调用还是在某种程度上转换为直接调用 GUI 线程上的方法?
采纳答案by CMerat
The method.Invoke()
call executes the delegate on the current executing thread. Using the BeginInvoke(method)
ensures that the delegate is called on the GUI thread.
该method.Invoke()
调用在当前执行线程上执行委托。使用BeginInvoke(method)
可确保在 GUI 线程上调用委托。
This is the correct way of avoiding code duplication when the same method can be called both from the GUI thread and other threads.
当可以从 GUI 线程和其他线程调用相同的方法时,这是避免代码重复的正确方法。
回答by Nick Whaley
It makes the call on the same thread. You can check by stepping through the code. There is nothing wrong with that approach.
它在同一个线程上进行调用。您可以通过单步执行代码进行检查。这种方法没有任何问题。
回答by Samuel
For WinForms, calling Control.Invoke(Delegate)
sends a message to the UI's thead's message pump. The thread then processes the message and calls the delegate. Once it has been processed, Invoke
stops blocking and the calling thread resumes running your code.
对于 WinForms,调用会Control.Invoke(Delegate)
向 UI 的 thead 的消息泵发送一条消息。然后线程处理消息并调用委托。处理完毕后,Invoke
停止阻塞,调用线程继续运行您的代码。
回答by GregC
Keep in mind that Control.InvokeRequired returns false if you are on background thread AND Control.IsHandleCreated is false. I would safeguard the code with a Debug.Assert that checks for unmanaged handle creation.
请记住,如果您在后台线程上且 Control.IsHandleCreated 为 false,则 Control.InvokeRequired 返回 false。我会使用 Debug.Assert 来保护代码,以检查非托管句柄的创建。
回答by Stephan Ryer
Personally I like this method:
我个人喜欢这种方法:
private void ExecuteSecure(Action a)
{
if (InvokeRequired)
BeginInvoke(a);
else
a();
}
And then you can write one-liners like this:
然后你可以像这样写单行:
ExecuteSecure(() => this.Enabled = true);