自动化InvokeRequired code模式 [英] Automating the InvokeRequired code pattern
问题描述
我已经痛苦地意识到人们需要多么经常写在事件驱动的GUI code,以下code模式,其中
I have become painfully aware of just how often one needs to write the following code pattern in event-driven GUI code, where
private void DoGUISwitch() {
// cruisin for a bruisin' through exception city
object1.Visible = true;
object2.Visible = false;
}
变成了:
private void DoGUISwitch() {
if (object1.InvokeRequired) {
object1.Invoke(new MethodInvoker(() => { DoGUISwitch(); }));
} else {
object1.Visible = true;
object2.Visible = false;
}
}
这是在C#中的尴尬格局,既要记住,和打字。有没有人想出了一些快捷方式或构造,自动化这在一定程度上?这将会是冷静,如果有一个功能附加到做此检查对象,而无需经过所有这些额外的工作,如 object1.InvokeIfNecessary.visible = TRUE $ C $方式C>键入快捷方式。
This is an awkward pattern in C#, both to remember, and to type. Has anyone come up with some sort of shortcut or construct that automates this to a degree? It'd be cool if there was a way to attach a function to objects that does this check without having to go through all this extra work, like a object1.InvokeIfNecessary.visible = true
type shortcut.
previous <一个href=\"http://stackoverflow.com/questions/747210/whats-wrong-with-calling-invoke-regardless-of-invokerequired\">answers讨论的只是打电话的invoke()每次不切实际,甚则调用()语法既低效的还是的尴尬来应对。
Previous answers have discussed the impracticality of just calling Invoke() every time, and even then the Invoke() syntax is both inefficient and still awkward to deal with.
那么,有没有人想出任何快捷方式?
So, has anyone figured out any shortcuts?
推荐答案
李某的方法可以进一步简化
Lee's approach can be simplified further
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
// See Update 2 for edits Mike de Klerk suggests to insert here.
if (control.InvokeRequired) {
control.Invoke(action);
} else {
action();
}
}
和可以这样调用
richEditControl1.InvokeIfRequired(() =>
{
// Do anything you want with the control here
richEditControl1.RtfText = value;
RtfHelpers.AddMissingStyles(richEditControl1);
});
有没有必要通过控制作为参数给委托。 C#自动创建一个封闭。
There is no need to pass the control as parameter to the delegate. C# automatically creates a closure.
更新
据其他几个海报控制
可概括为 ISynchronizeInvoke
:
According to several other posters Control
can be generalized as ISynchronizeInvoke
:
public static void InvokeIfRequired(this ISynchronizeInvoke obj,
MethodInvoker action)
{
if (obj.InvokeRequired) {
var args = new object[0];
obj.Invoke(action, args);
} else {
action();
}
}
DonBoitnott指出,除非控制
的 ISynchronizeInvoke
接口,需要一个对象数组的调用
方法的操作参数列表
。
DonBoitnott pointed out that unless Control
the ISynchronizeInvoke
interface requires an object array for the Invoke
method as parameter list for the action
.
更新2
由麦克·德克勒克修改建议(见插入点在1 code段评论)
Edits suggested by Mike de Klerk (see comment in 1st code snippet for insert point):
// When the form, thus the control, isn't visible yet, InvokeRequired returns false,
// resulting still in a cross-thread exception.
while (!control.Visible)
{
System.Threading.Thread.Sleep(50);
}
请参见下面ToolmakerSteve的评论关于这个建议关注。
See ToolmakerSteve's comment below for concerns about this suggestion.
这篇关于自动化InvokeRequired code模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!