- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我已经痛苦地意识到需要在事件驱动的 GUI 代码中编写以下代码模式的频率,其中
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
类型快捷方式,那就太好了。
上一个 answers已经讨论了每次只调用 Invoke() 的不切实际,即使那样 Invoke() 语法既低效又仍然难以处理。
那么,有没有人想出任何捷径?
最佳答案
李的方法可以进一步简化
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);
});
无需将控件作为参数传递给委托(delegate)。 C# 自动创建一个 closure .
如果你必须返回一个值,你可以使用这个实现:
private static T InvokeIfRequiredReturn<T>(this Control control, Func<T> function)
{
if (control.InvokeRequired) {
return (T)control.Invoke(function);
} else {
return function();
}
}
更新:
根据其他几位发帖人的说法,Control
可以概括为 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 指出,与 Control
不同,ISynchronizeInvoke
接口(interface)需要一个用于 Invoke
方法的对象数组作为 action 的参数列表
。
更新 2
Mike de Klerk 建议的编辑(请参阅第一个代码片段中的注释以获取插入点):
// 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's和 nawfal's对此建议的疑虑,请在下方发表评论。
关于c# - 自动化 InvokeRequired 代码模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2367718/
InvokeRequired 和 somecontrol.InvokeRequired 有什么区别? 像这样, delegate void valueDelegate(string value); p
这怎么可能?我有 Windows 窗体控件,从 System.Windows.Forms.Form 派生,WebBrowser 控件包含在此窗体中。 Webbrowser 对象实例是在表单的构造函数中
我有一个事件处理程序,我想在创建对象的原始线程中处理它,这样它就不会阻塞。使用表单,很容易使用 InvokeRequired 将其强制到原始线程。但是如果你的类不是表单,你怎么做呢? 谢谢, 下午 最
我知道您必须调用才能进行跨线程更新。但是,如果不需要 Invoke,您能否像需要 Invoke 时那样调用代码? 所以不是这个: if(rtbSearchResults.InvokeRequired)
这个问题在这里已经有了答案: What's wrong with calling Invoke, regardless of InvokeRequired? (6 个答案) 关闭 1 年前。 我的同
当我想在 Windows 窗体工作时使用委托(delegate)类进行调用时,我总是必须使用 InvokeRequired。没关系。但是谁在它工作时更改了 InvokeReuqired 属性。请检查这
UI 线程偶尔会在以下方法中的语句 'if (this.InvokeRequired)' 处挂起。 你能帮我找出问题的原因吗 public void OnModuleInitializationC
我一直在编写一个 API 来促进与串行端口的通信。我正在进行一些重构和一般清理,想知道是否有办法避免以下问题。 API 中的主类能够不断从端口读取数据,并在读取字节与特定正则表达式匹配时引发包含值的事
我想让我的 getter 线程安全。当我这样做时,出现错误: public ApplicationViewModel SelectedApplication { get
我来找你是想看看是否有人知道如何解决我在迁移到 ActiveMQ 时遇到的问题。我在这个项目中使用 ActiveMQ 发送通知(在 C# 中),在完成实现后我发现了一些关于线程问题的错误。 (我知道该
这是我的代码: foreach (var pathCartella in folderList) { try { // some operation i
我一直在寻找这个问题的答案,但似乎找不到满意的答案。也许这里有人可以启发我。 我有一个 BindingList 的后代存储对 SynchronizationContext 的引用对象以便在 UI 线程
我有一个 UserControl,上面有一个名为 mTreeView 的 TreeView 控件。我可以从多个不同的线程获取数据更新,这些会导致 TreeView 被更新。为此,我设计了以下模式:所有
这个问题在这里已经有了答案: Invoke or BeginInvoke cannot be called on a control until the window handle has been
在我的应用程序中,我有一个负责所有数据库操作的类。它从主类调用,并在操作完成后使用委托(delegate)调用方法。因为它是异步的,所以我必须在我的 GUI 上使用 invoke,所以我创建了一个简单
我是一名新手程序员,所以我在这里可能完全错了,但这个问题比它应该的更让我烦恼。 这实际上是 this 的跟进问题。 公认的答案是,您必须调用 InvokeRequired 以避免一些开销,因为您有可能
这个问题在这里已经有了答案: What's wrong with calling Invoke, regardless of InvokeRequired? (6 个答案) 关闭去年。 我知道,当从
我已经痛苦地意识到需要在事件驱动的 GUI 代码中编写以下代码模式的频率,其中 private void DoGUISwitch() { // cruisin for a bruisin' t
从.NET 4.0开始,TPL可以执行异步任务。如果您正在阅读msdn,则所有与窗体/UI交互的异步操作仍将使用InvokeRequire ... Invoke()模式。 我要问的是有原因吗?据我了解
首先,我在 Window.Forms 开发方面经验不足。但是我发现 InvokeRequired 检查,对于控件,在线程应用程序中使用时有点乏味。我创建了一个静态方法,我认为它可以解决我乏味的 Inv
我是一名优秀的程序员,十分优秀!