【问题标题】:Which C# assembly contains Invoke?哪个 C# 程序集包含 Invoke?
【发布时间】:2010-06-24 11:53:57
【问题描述】:

另一个问题:为什么 VS10 如此热衷于抱怨 Invoke?

在我继续让我的应用工作成为世界上最好的 C# 程序员的过程中,我决定线程是一件好事™。

MSDN 有一篇关于制作thread-safe calls to controls 的有用文章,但它(以及似乎所有其他关于该主题的文章)间接引用了一个名为 Invoke 的方法。有时甚至是 BeginInvoke,I've read is to be preferred

如果我能让 Visual Studio 识别 Invoke,这一切都会很棒。 MSDN 说it is contained in the System.Windows.Forms assembly,但我已经在“使用”它了。可以肯定的是,我也尝试过使用 System.Threading,但无济于事。

我需要跳过哪些环节才能让调用正常工作?

【问题讨论】:

  • “Visual Studio 识别调用”是什么意思?智能感知?
  • 您是说在与当前执行线程不同的线程上创建的控件上调用方法吗?
  • 当您成为世界上最好的 C# 程序员时,您可能会意识到线程是一件非常糟糕的事情。或者,至少,显式管理线程是一件坏事。
  • @Eric 你提出了另一个问题:stackoverflow.com/questions/3110154/…

标签: c# visual-studio-2010 multithreading invoke


【解决方案1】:

Invoke 在控制范围内。 IE。 Control.Invoke();

没有办法直接调用 Invoke 因为System.Windows.Forms 中没有这样的方法。 Invoke 方法是一个控制成员。

这是我之前制作的example

public delegate void AddListViewItemCallBack(ListView control, ListViewItem item);
public static void AddListViewItem(ListView control, ListViewItem item)
{
    if (control.InvokeRequired)
    {
        AddListViewItemCallBack d = new AddListViewItemCallBack(AddListViewItem);
        control.Invoke(d, new object[] { control, item });
    }
    else
    {
        control.Items.Add(item);
    }
}

【讨论】:

    【解决方案2】:

    您需要在包含它的东西的实例上调用Invoke - 如果您使用的是 Windows 窗体,那将是一个控件:

    control.Invoke(someDelegate);
    

    或者对于表单中的代码,您可以使用隐式 this 引用:

    Invoke(someDelegate);
    

    您不需要经历任何特定的障碍。如果 Visual Studio 抱怨,请指定编译器错误和它抱怨的代码。 Invoke 这里没有什么特别之处。

    【讨论】:

      【解决方案3】:

      winform InvokeControl 的一个实例方法——你只需要一个控件的实例(在很多情况下可以是this)。例如:

      txtBox.Invoke(...);
      

      如果您想要抽象,也可以通过接口或同步上下文访问它 - 但最简单的方法是通过事件在 UI 处处理它,在这种情况下可以方便地使用控件。

      【讨论】:

        【解决方案4】:

        如果你真的想成为世界上最好的 c# 程序员,你必须明白线程不是一件好事,除非使用得当。

        跨线程更新 UI 通常表明您正在滥用线程。

        无论如何,使用using System.Windows.Forms 是不够的,您必须将其添加到引用中。在项目浏览器中右键单击References,然后添加引用并选择System.Windows.Forms

        【讨论】:

        • 谢谢!你走了又走了,让我很困惑。 (这是您可能想回答的另一个问题:stackoverflow.com/questions/3110154/…
        • “跨线程更新 UI 通常表明您正在滥用线程。”哇,这对我来说是新的。所以如果我在一个 BG 线程中放了一个长的分析操作来保持 UI 响应,但是用户希望快速看到增量结果,所以我的 BG 线程定期将结果返回给 UI 线程,这是滥用吗?你现在要揭示更好的解决方案吗?
        • 是的,很简单:使用事件。 BG Thread提供了一个UI可以订阅的事件,即“FileCopied”、“NumberCalculated”等。UI可以订阅它,如果你将代码从winforms切换到WPF,后台worker仍然可以正常工作,实现多语言用户界面,将无聊的对话框变为花哨的对话框等
        • @Conrad:dbemerlin 有一个很好的观点。另一种思考方式是分析操作的业务是分析,而不是 UI。分析函数中不应该有任何任何逻辑来直接更新 UI;这不是它关心的问题。如果一个分析函数作为服务提供一个回调来描述它的当前状态,很好,这它的关注点。该回调对 UI 的影响可以由 UI 代码处理。
        • 好吧,只是意思的误会。实际上,我的 BG 线程确实 完全按照你们的主张使用了一个事件;对我来说,听起来仍然像是“跨线程更新 UI”。事实上,我的事件在 BG 线程上触发(因为这是触发方法知道的唯一线程)。但是该事件触发了一个 UI 方法(因此也运行在 BG 线程上),然后必须“跨线程”调用另一个 UI 方法。
        【解决方案5】:

        Invoke 是一种对象方法,通常在 Forms 库中的 Controls 和一些异步类中找到。您当然需要特定的对象才能在 那个 控件/类上调用 Invoke。

        【讨论】:

          【解决方案6】:

          您可能试图从类中调用Invoke(即不是从FormControl 中)。将你的代码移出类并移到窗体或控件中,你会看到Invoke 编译并正常工作(严格来说,你的代码应该引用this.Invoke,这使得方法的来源清晰,但@987654326 @ 也可以工作,因为它假定 this)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-09-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-30
            • 1970-01-01
            • 2015-02-12
            相关资源
            最近更新 更多