调用(委托)

2024-03-05

谁能解释一下上面写的这个声明link http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke.aspx

Invoke(Delegate):

在拥有该委托的线程上执行指定的委托控件的底层窗口句柄。

任何人都可以解释这意味着什么(尤其是粗体)我无法清楚地理解


这个问题的答案在于 C# 控件的工作原理

Windows 窗体中的控件绑定到特定线程,而不是 线程安全。因此,如果您从 不同的线程,您必须使用控件的调用方法之一 将调用编组到正确的线程。该属性可用于 确定是否必须调用调用方法,这在以下情况下很有用: 你不知道哪个线程拥有一个控件。

From Control.InvokeRequired http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired%28v=vs.90%29.aspx

实际上,Invoke 的作用是确保您调用的代码发生在控件“生存”的线程上,从而有效防止跨线程异常。

从历史的角度来看,在.Net 1.1中,这实际上是允许的。这意味着您可以尝试从任何后台线程在“GUI”线程上执行代码,这通常会起作用。有时它只会导致您的应用程序退出,因为您在 GUI 线程正在执行其他操作时有效地中断了它。这是跨线程异常- 想象一下当 GUI 正在绘制其他内容时尝试更新 TextBox。

  • 哪个行动优先?
  • 两者有可能同时发生吗?
  • GUI 需要运行的所有其他命令会发生什么情况?

实际上,您正在中断队列,这可能会产生许多不可预见的后果。 Invoke 实际上是一种“礼貌”的方式,可以将您想要执行的操作放入队列中,并且从 .Net 2.0 开始,通过抛出异常强制执行此规则无效操作异常 http://msdn.microsoft.com/en-gb/library/system.invalidoperationexception.aspx.

要了解幕后实际发生的情况以及“GUI 线程”的含义,了解什么是消息泵或消息循环很有用。

这实际上已经在问题中得到了回答”什么是消息泵 https://stackoverflow.com/questions/2222365/what-is-a-message-pump”,建议阅读以了解与控件交互时所绑定的实际机制。

您可能会发现有用的其他阅读材料包括:

开始调用是怎么回事 http://www.codeproject.com/Articles/10311/What-s-up-with-BeginInvoke

Windows GUI 编程的基本规则之一是,只有 创建控件的线程可以访问和/或修改其内容 (除了一些有记录的例外情况)。尝试从任何其他地方做 线程,你会得到不可预测的行为,从死锁到 更新一半的 UI 除外。那么更新的正确方法 来自另一个线程的控制是将适当的消息发布到 应用程序消息队列。当消息泵到达时 执行该消息,控件将在同一时间得到更新 创建它的线程(记住,消息泵在主线程上运行 线)。

并且,对于具有代表性示例的更多代码概述:

无效的跨线程操作 http://www.perceler.com/articles1.php?art=crossthreads1

// the canonical form (C# consumer)

public delegate void ControlStringConsumer(Control control, string text);  // defines a delegate type

public void SetText(Control control, string text) {
    if (control.InvokeRequired) {
        control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text});  // invoking itself
    } else {
        control.Text=text;      // the "functional part", executing only on the main thread
    }
}

一旦您欣赏了 InvokeRequired,您可能希望考虑使用扩展方法来包装这些调用。 Stack Overflow 问题中巧妙地涵盖了这一点清理充斥着 Invoke required 的代码 https://stackoverflow.com/questions/3874134/cleaning-up-code-littered-with-invokerequired.

还有一个更进一步的写下历史上发生的事情 http://ikriv.com/dev/dotnet/MysteriousHang.html这可能令人感兴趣。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用(委托) 的相关文章

随机推荐

  • 如何计算具有共同列名的不同数据框之间的差异

    我有三个数据帧 并尝试计算由数据帧 1 调节的两个数据帧 Df2 和 Df3 之间的差异 如以下示例中所述 我有三个数据帧 Df1 Df2 和 Df3 它们具有通用名称 第一步 在 Df1 中 我想将 标准 列的值与所有三列 Das Dss
  • 有没有办法从跟踪生命周期的任何地方获取给定起点的请求的完整跟踪?

    有没有办法从跟踪生命周期的任何地方获取完整的跟踪请求 基本上 如果我有跟踪的中间点或终点 我可以使用这些点来获取请求的完整跟踪吗 我想构建一个跟踪服务 在 Golang 中 只要用户在请求跟踪期间随时提供点 跨度 该服务就可以返回请求的完整
  • 机器人类类似于 android 类[重复]

    这个问题在这里已经有答案了 可能的重复 Android API 如 java awt Robot https stackoverflow com questions 4416228 android api like java awt rob
  • SQL对具有重叠时间跨度的数据进行分组

    我需要根据记录开始和结束时间通过重叠时间跨度将彼此相关的数据分组在一起 SQL fiddle在这里 http sqlfiddle com 18 87e4b 1 0 http sqlfiddle com 18 87e4b 1 0 我构建的当前
  • 更改 WPF 应用程序中的默认打印机

    我正在寻找更改 WPF 应用程序中默认打印机的最佳方法 以下是我们希望应用程序能够执行的步骤 从下拉列表中选择映射到打印机名称的位置 将默认打印机更改为映射名称 启动 IE 并指向 SSRS 报告 然后 用户将从 IE 打印报告 IE 将使
  • 绘图:平行坐标图:轴样式

    我真的很喜欢平行坐标图 情节很好 但我刚刚遇到了一个需要帮助的问题 某些坐标是否可以使用基于 log10 的轴 正如您在下面的示例中看到的 执行 log10 变换可以更好地区分较小的值 然而 通过转换数据 我们失去了解释这些值的能力 我更喜
  • 检查每个 Node.js 请求的身份验证凭据

    我使用 Node js 与 Express 和 connect auth 来对用户进行身份验证 这是请求 index时的验证 if req isAuthenticated res redirect dashboard else res re
  • 将 [0-255] 整数范围转换为 [0.0-1.0] 浮点范围

    在 WxWidget 中 颜色由 RGB 整数三元组表示 要使用 0 0 1 0 浮点三元组表示与其他库交互 需要进行转换 WxPython Numpy 或 Python 中是否已经存在这样的转换函数 您可以将每个元素除以 255 或 25
  • 解析数据 org.json.JSONException 时出错:输入结束于字符 0

    解析 JSON 时出现错误 解析数据 org json JSONException 时出错 在字符 0 处输入结束 错误日志 04 19 20 51 00 635 E ViewRootImpl 24857 sendUserActionEve
  • 自定义 Django 模型字段中的“对象没有属性”

    我正在尝试创建一个 Django 模型字段 该字段表示 HTML 中包含天 小时 分钟和秒文本输入字段的持续时间 并使用 ical 格式 RFC5545 将持续时间存储在数据库中 这与我的问题有关如何在 Django 中创建一个 ical
  • 如何在 Unix 中批量执行 svn mv

    我想将大量文件从一个目录批量移动到svn中的另一个目录 不幸的是 svn 只支持一次移动一个文件 基本上我想移动某种类型的文件 xml 到一个完全不同的目录 例如mv foo 酒吧 xml forbar xml 我尝试使用 find 并使用
  • 如何将 PIL 添加到 Eclipse 中的 PyDev,以便我可以导入它并在我的项目中使用它?

    我正在尝试在我的项目中使用 PIL 但 pydev 似乎无法在我的项目中找到它 首先 当我进入 python shell 时我可以看到它 我可以导入它并在 python sys path 中看到它 其次 我将其添加到 eclipse 中的
  • 带有可选小时数的 TimeSpan FormatString

    我有一个时间跨度 ts 主要有分钟和秒 但有时也有几个小时 我想要ts返回一个格式化的字符串 该字符串将给出以下结果 3 30 hours not displayed showing only full minutes 13 30 1 13
  • 取消从应用程序调用 Web 服务

    我有一个 winform 应用程序 有两个按钮 GetData 和 Close 在 GetData 上 我从 Web 服务检索一些数据 而 Close 只是关闭对话框 我在一个单独的线程上调用网络服务 该线程是类实例变量 如果从 Web 服
  • 使用正则表达式进行 C Sharp 文件夹搜索

    从顶级目录获取与特定正则表达式匹配的文件夹列表的最有效方法是什么 我目前只是递归地迭代子文件夹以查看它们是否与正则表达式匹配 如果匹配 我将使用目录路径获取文件名 目前 由于此目录中的文件夹数量较多 使用当前方法进行此搜索大约需要 50 分
  • 如何在反应路由中设置延迟功能?

    如何在 React js 上设置延迟函数 有没有什么方法可以在反应路由中添加或删除类 以便页面可以转换 添加 删除或切换类每次都应该有效 是否可以使用延迟功能添加 删除或切换路由类 或者我可以使用第三方库吗 import React fro
  • 在 Android 中获取 Google 地图时出错

    我正在开发一个 Android 应用程序 该应用程序需要 Google 地图 为此 我在以下链接中使用相同的示例 谷歌地图的链接 http www androidhive info 2013 08 android working with
  • Android-decodeBase64 导致应用程序崩溃

    我必须加密一个字符串 但应用程序无法达到加密方法 它在加载时崩溃 我正在使用 Apache Commons Codec 库 private EditText txtPass EditText findViewById R id txtPas
  • BxSlider 将最后一张幻灯片显示为第一张幻灯片

    我创建了 4 个滑块 最初 所有 4 个滑块都是隐藏的 显示 无 因此我使用此代码在单击其各自类别时显示相关滑块 滑块配置 touchEnabled true hideControlOnEnd true preloadImages all
  • 调用(委托)

    谁能解释一下上面写的这个声明link http msdn microsoft com en us library system windows forms control invoke aspx Invoke Delegate 在拥有该委托