【问题标题】:'System.InvalidOperationException' occurred in System.Windows.Forms.dll in Task任务中的 System.Windows.Forms.dll 中发生“System.InvalidOperationException”
【发布时间】:2012-03-02 03:38:54
【问题描述】:

我正在构建一个 Winform 应用程序,我想更新一个表示目录树的 TreeView。这个方法需要一两秒,所以我想并行运行它。

首先我在下面的代码中使用了 Task.Factory.StartNew(),但我收到了错误 'System.InvalidOperationException' occurred in System.Windows.Forms.dll in Task

Task loadTreeViewTask = Task.Factory.StartNew(() =>
        {
            try {
                directoryTreeView.Nodes.Clear();
                ....
                PopulateTreeView(directory, directoryTreeView.Nodes[0]);
            }
            catch (Exception e) {
               //Log
               //Change try/catch to CancellationToken
            }
        });

然后我看到Windows使用单线程UI,我发现我需要使用InvokeRequired:

directoryTreeView.Invoke((MethodInvoker)(() =>
{
  try {
    directoryTreeView.Nodes.Clear();
    ....
    PopulateTreeView(directory, directoryTreeView.Nodes[0]);
  }
  catch (Exception e) {
   //Log
   //Change try/catch to CancellationToken
  }
}));

有更好的方法吗?

【问题讨论】:

  • 当您编写一个模型类,它在后台工作得更加努力并最终在某些检查点上调用自己的事件时,情况会变得更糟。您绝对不知道将如何使用事件。如果有人使用事件来更新视图,你就会陷入同样尴尬的境地。你做的事情显然是正确的。另一端也在正确使用事件,但是您的模型是基于线程的,并且发生了大爆炸……

标签: c# winforms task-parallel-library


【解决方案1】:

您的代码的第一部分将不起作用,因为您正在尝试更新在 UI 线程上创建的控件,因此,是的,您将需要使用 Invoke 方法。您不能从另一个线程更新在 UI 线程上创建的 UI 控件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    相关资源
    最近更新 更多