【问题标题】:Control.Invoke fails at second callControl.Invoke 在第二次调用时失败
【发布时间】:2010-12-21 17:19:17
【问题描述】:

我正在使用 .Net Compact Framework 2.0 SP2 和 C# 开发一个 Windows Mobile 5.0 及更高版本 应用程序。

我在方法中有这段代码:

if (listBox1.InvokeRequired)
{
    Invoke(new MethodInvoker(
        delegate() { listaBox1 = listaBox2; listBox1.Visible = true; }));
}
else
{
    listBox1 = listBox2;
    listBox1.Visible = true;
}

当我运行它时,它会在第二条语句 (listBox1.Visible = true;) 上抛出异常:

Control.Invoke 必须用于与在单独线程上创建的控件进行交互。

发生了什么事?

【问题讨论】:

  • 您应该使用 BeginInvoke 而不是 Invoke 来防止死锁。

标签: c# winforms windows-mobile compact-framework invoke


【解决方案1】:

您的两个 ListBox 是在不同的线程上创建的。也就是说,几乎在所有情况下,这都是一个非常非常糟糕的主意。

【讨论】:

    【解决方案2】:

    这个场景中有2个ListBox引用的原因

    1. 列表框1
    2. 列表框2

    您只检查了 listBox1 的 InvokeRequired 成员。然而,您实际上最终在 listBox2 最初指向的实例上调用了 .Visible。根据产生的行为,很可能 2 个引用最初指向 ListBox 的 2 个不同实例。

    要解决此问题,请检查 listBox2 上的 InvokeRequired,因为那是您最终实际使用的那个。

    【讨论】:

    • 虽然我认为你基本上是对的,但这并不能解释为什么 listBox2 位于 listBox1 之外的另一个线程上,因为两者似乎属于同一个表单,应该在一个线程上。您可以在与父线程不同的线程上创建控件吗?毕竟这会修改 Controls 属性...
    • 有一个线程加载数据以显示在 listBox 上。列表框是自定义控件。如果我将数据直接加载到 listBox1,我会收到很多错误消息(必须使用 Control.Invoke...)。这就是为什么有两个列表框的原因。
    • @OregonGhost — 是的,可以在其他线程上创建控件,规则是一样的:与控件的所有交互(调用 InvokeRequired 除外)都应该在创建线程上。
    • 它需要一些其他条件来保持,例如 listBox1 从未显示。
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    相关资源
    最近更新 更多