自动化InvokeRequired code模式 [英] Automating the InvokeRequired code pattern

查看:162
本文介绍了自动化InvokeRequired code模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经痛苦地意识到人们需要多么经常写在事件驱动的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 键入快捷方式。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆