【问题标题】:How to extract Invoke call to a method with a lambda parameter如何提取对具有 lambda 参数的方法的调用调用
【发布时间】:2020-04-06 01:24:27
【问题描述】:

我发现自己编写了很多这样的代码来从 BackgroundWorker 更新 UI 线程(_instance 是对 Main 类的引用):

_instance.Invoke((Action)(() =>
{
    _instance.DgvResults.DataSource = Results;
    _instance.LblStatus.Text = @"Done!";
}));

我想将此块提取到一个方法中,这样我就可以这样调用它:

RunOnUIThread(() => _instance.DgvResults.DataSource = Results);

换句话说,目标是能够将包含我想在 UI 线程上运行的指令的 lambda 传递给此方法。我已经能够在 Java 中做到这一点,但我对 C# 还是很陌生,不知道如何解决这个问题。任何指导将不胜感激。

【问题讨论】:

  • 所以 UI 线程正在继续更新 UI 的东西?更新引用某些甚至尚未更改的内容的“每一帧”并不是那么可取...
  • 这个后台工作人员对 UI 线程的要求非常低,但我的强迫症患者更愿意将这两个调用替换为对方法的单行调用!
  • 在 UI 线程 ProgressChangedRunWorkerCompleted 上执行的 BackgroundWorker 事件中执行函数。后台工作人员访问外部资源(数据库、文件或 Web 服务)的替代方法 - 使用没有后台工作人员的异步方法
  • RunOnUIThread(() => _instance.DgvResults.DataSource = Results)_instance.Invoke(() => _instance.DgvResults.DataSource = Results) 有何不同/更好?在我看来,它们基本上是一样的。如果您将每个语句包装在调用中,这只是一个单行,这实际上会比传统方法更糟糕。如果您真的不喜欢显式调用Invoke(),则应该在不需要的地方使用不同的方法,例如利用BackgroundWorker 中现有的跨线程机制或使用WPF(它会自动执行很多操作)
  • 好电话,我已经将我可以的调用单列起来,并将需要一次发送多个指令的调用保持原样。 “BackgroundWorker 中现有的跨线程机制”指的是什么?

标签: c# methods lambda parameters


【解决方案1】:

我不确定这是你想要的,但我认为你可以使用eventdelegate。

// In UI-related code
public event Action UpdateUI;

您可以添加想要在发生变化时调用的 lambda。

// Other codes
_uiCode.UpdateUI += () => _instance.DgvResults.DataSource = Results;

// More other codes
_uiCode.UpdateUI += () => UpdateSomethingTopPanel();
_uiCode.UpdateUI += () => UpdateSomethingBelow();
...

并通过一行代码调用这些函数:

// If nothing has added to event, invoking would cause nullref, 
// so we have to check null.
UpdateUI?.Invoke();

但要小心,向event 添加内容不会检查重复成员。您只需调用上述代码一次。

【讨论】:

  • 所以如果我理解正确,我将不得不为每个单独的调用创建一个新的事件操作,以便每次都重置它?
  • “不检查重复成员”意味着如果你添加两次相同的东西,当你调用事件时它会调用两次,这会导致错误,或者至少会破坏性能。如果不一样,你可以随意添加,一次用Invoke()调用add lambdas
猜你喜欢
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多