【问题标题】:Multi Threading Issue - Need Event after thread completes多线程问题 - 线程完成后需要事件
【发布时间】:2012-12-12 23:08:20
【问题描述】:

我正在设计一个多线程进程,我在其中创建一个线程来执行一些处理,以免锁定 UI。但是,当这个线程完成时(如果它成功完成而没有错误),我需要一个事件,以便我可以在 UI 线程上执行一个方法来正确更新 UI。

我怎样才能正确地做到这一点?

我的线程简单代码:

Thread t = new Thread(new ThreadStart(GetAppUpdates));
t.Start();

现在我需要知道线程何时完成,但我觉得我不想实现会不断检查线程状态的代码,因为它会导致 UI 延迟。

(我知道使用 backgroundworker 会更容易,但我不想让这个进程使用 backgroundworker,因为这个线程不能是后台)。

有没有办法在线程对象完成时触发它们的事件?完成 ThreadFinished() 事件的最佳方法是什么?线程成功完成后,我的代码必须在主 UI 上执行。

【问题讨论】:

  • 如果你有一个 UI,为什么你需要它不是后台线程?这将阻止进程终止...无论如何,我建议使用Task 而不是BackgroundWorker...
  • BackgroundWorker 就是为此而设计的。 “不能成为背景”是什么意思。后台线程与另一个线程相同。
  • @JonSkeet 我理解的方式是 background = true 或 backgroundworker 线程不会导致应用程序在关闭前等待。用户可以随时关闭应用程序,但我需要在关闭之前完成所有线程处理。
  • @Encryption: 无论如何,进程总是可以被用户终止……如果用户已经关闭了 UI,你想在线程完成后在哪里执行额外的代码?
  • 我的需要是,我不希望用户能够关闭 UI,这会导致我的进程突然结束。这就是为什么我没有选择 backgroundworker

标签: c# multithreading


【解决方案1】:

传递新的匿名方法,该方法调用GetAppUpdates() 和其他一些方法,通知您更新已完成:

Thread t = new Thread(new ThreadStart(() => { GetAppUpdates(); Completed(); }));
t.Start();

Completed 方法将在你的GetAppUpdates() 方法执行后被调用:

private void Completed()
{
   if (InvokeRequired)
   {
      Invoke((MethodInvoker)delegate() { Completed(); });
      return;
   }

   // update UI
}

顺便说一句这可以完成工作,但我最好使用 BackgroundWorker - 它是为此类任务设计的,它的 RunWorkerCompleted 事件处理程序将在 UI 线程上运行,这非常方便。

【讨论】:

  • 啊有趣...所以在为该方法调用 Invoke 之后,我又是 UI 安全了吗?
  • @Encryption 完全正确,这就是为什么我们有InvokeRequired 属性和Invoke 方法:)
  • 很好......这胜过为每个 UI 控件调用 Invoke
  • 效果很好。可能不是最流行的多线程应用程序编码方式,但在这种情况下,我有一个特殊的需求,即 backgroundworker 无法满足。谢谢
【解决方案2】:

我建议使用Task 而不是线程来编写这个。由于您在完成中更新 UI,因此您需要确保它在 UI 线程中运行。这可以通过 continuation 来完成:

Task task = Task.Factory.StartNew(() => GetAppUpdates());
task.ContinueWith(t => UpdateUserInterface(),
                     TaskScheduler.FromCurrentSynchronizationContext());

【讨论】:

  • 只有.Net 4.0 吗?我被困在 3.5
  • @Encryption 是,.Net 4.0 上可用的任务
  • @Encryption 如果您安装旧版本的 Rx 扩展(包括 TPL 的反向移植),您可以在 3.5 中使用它
猜你喜欢
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多