首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >InvalideOperationException / invoke

InvalideOperationException / invoke
EN

Stack Overflow用户
提问于 2013-06-06 19:51:50
回答 2查看 309关注 0票数 1

下面的代码用于触发调用(减少了代码,为了更清楚起见,我省略了本例中的错误处理)

代码语言:javascript
运行
复制
public static void InvokeIfNecessary(this Control control, MethodInvoker methodInvoker)
{
    if (control != null && !control.IsDisposed && !control.Disposing)
    {

        if (control.InvokeRequired)
        {
            control.Invoke(methodInvoker);
        }
        else
        {
            methodInvoker();
        }
    }
}

正常情况下,它工作得很好,但有时如果我调用表单的方法,会给出一个InvalidOperationException。要调用的逻辑示意图方法

代码语言:javascript
运行
复制
// in a Frm2:
internal void UpdateSomething()
{
    List<NO> myObjects = frmMain.NO.GetNOs();

    if (null != myObjects)
    {
        this.InvokeIfNecessary(() =>
        {
            layoutControlGroup.BeginUpdate(); // DevExpress Layoutcontrolgroup

            foreach (NO aObject in myObjects)
            {
                if(...) // if already a control for the object exist update it.
                {
                    // update

                }
                else
                {
                    // add item
                    LayoutControlItem layoutControlItem = new LayoutControlItem();
                    // create new control
                    Control control = CreateNewControl(aObject);
                    layoutControlItem.Control = control;
                    // do some stuff with visibility and size of control
                    ...
                    layoutControlGroup.AddItem(layoutControlItem); // <-- And here the InvalidOperationException occurs.
                    /// The message is (translated
                    /// InvalidOperationException was not handled by usercode
                    /// The acces on the Control FrmMain was done from another Thrad then the thread which created it.
                    ...;
                }
            }


            ...;

            layoutControlGroupCA.EndUpdate();
        });
    }
}

好吧..。我必须承认我有一个概念上的问题。

为什么在这里抛出异常?

Frm2方法创建一个新元素(不是只有一个字符串和一个带有字符串和布尔值的结构)。只能在UpdateSomething()方法中访问该元素。layOutControlGroup是Frm2的成员。

因此,在我看来,只有应该在Frm2线程中创建的新控件才应该附加到Frm2特定控件。

那么为什么它会坚持在FrmMain中呢?(主窗体,它调用窗体的方法来通知项的更新)

P.S. this.InvokeIfRequired <-这实际上是Frm2 ...

EN

回答 2

Stack Overflow用户

发布于 2013-06-06 20:03:45

因此,正如我们所看到的,( begin) invoke总是有问题。请改用BeginInvoke。是我的提示。通常它会说,控件上的begin invoke在创建句柄的同一线程中执行方法。

但是看起来,form2的句柄不是在同一线程中创建的,或者它可能还不存在。请试着检查并验证这一点。

阿。顺便说一句,在visual studio中,当异常被抛出时,标记它们。这有助于发现错误。

票数 0
EN

Stack Overflow用户

发布于 2013-06-06 20:32:04

我认为你用错误的控件检查了InvokeRequired

您需要使用InvokeRequired检查的是layoutControlGroup,但是您的扩展方法使用代码this.InvokeIfNecessary检查表单,其中this为Frm2。

此外,您调用了layoutControlGroup.BeginUpdate(),但layoutControlGroupCA.EndUpdate()似乎与用法不对称。

代码的更正可能是:

代码语言:javascript
运行
复制
internal void UpdateSomething() {
    var myObjects=frmMain.NO.GetNOs();

    if(null!=myObjects) {
        MethodInvoker beginUpdate=() => layoutControlGroup.BeginUpdate();
        MethodInvoker endUpdate=() => layoutControlGroup.EndUpdate();

        layoutControlGroup.InvokeIfNecessary(beginUpdate);

        foreach(NO aObject in myObjects)
            if(SomeCondition) {
                // update
            }
            else {
                LayoutControlItem layoutControlItem=new LayoutControlItem();
                Control control=CreateNewControl(aObject);
                layoutControlItem.Control=control;

                MethodInvoker addItem=
                    () => {
                        layoutControlGroup.AddItem(layoutControlItem);
                    };

                layoutControlGroup.InvokeIfNecessary(addItem);
            }

        layoutControlGroup.InvokeIfNecessary(endUpdate);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16961404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档