【问题标题】:Open window inside a thread在线程内打开窗口
【发布时间】:2012-07-19 10:21:21
【问题描述】:

我需要一些帮助来解决这个问题。

场景:

  1. 启动 3 个线程(每个线程具有不同的值)(使用 TPL 或使用 ThreadPool)
  2. 每个线程收集一些不同的数据
  3. 为每个线程打开一个窗口,其中包含来自线程的特定数据
  4. 用户在每个窗口中输入一些值
  5. 值被发送回特定线程
  6. 一些额外的工作
  7. 完成

现在,问题是,我无法在线程内打开窗口,因为它必须是 GUI 线程 (ApartmentState.STA)。

知道如何处理窗口/用户输入的问题吗?

【问题讨论】:

  • 你不应该让线程等待用户输入。这就是问题的根源。
  • 这对我来说没有意义。为什么要同时打开三个窗口?用户将无法同时使用所有这些。
  • “现在,问题是,我无法在线程中打开窗口”打开窗口已经是线程:)
  • @svick - 这确实是一个问题。有几种方法可以做 OP 想要的事情,但这是一个普遍的问题:( 来自其他线程的 UI 窗口往往会在用户已经填写一个时弹出,窃取焦点并且通常会惹恼用户。它可以解决,例如,仅使用一个表单,在线程通知的新标签页中添加一个新框架,而不是从原始页面获取焦点 - 用户可以在填写/确定后依次填写其他页面第一个。
  • @HenkHolterman - 是的,在大多数情况下,你是对的 - 线程“中间”的 UI 很痛苦。然而,有时这是不可避免的。现在引起我问题的应用程序就是这样一个(尽管它是 Delphi,而不是 C#,但同样的问题)。它有多个线程运行脚本解释器实例(REMobjects Pascal)。一个命令是“GetUserInput()”。除了向 UI 发送消息以创建 Edit/RadioButton/List/Checkbox/whatever 表单并在解释器线程可以“执行”下一行脚本之前等待用户输入完成之外,我没有看到任何其他实现方式.

标签: c# wpf multithreading threadpool task-parallel-library


【解决方案1】:

http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/

解释如何为每个窗口设置单独的 UI 线程。

private void OnCreateNewWindow( object sender,   RoutedEventArgs e)
{
 Thread thread = new Thread(() =>
{
 Window1 w = new Window1();
 w.Show();

 w.Closed += (sender2, e2) =>
  w.Dispatcher.InvokeShutdown();

 System.Windows.Threading.Dispatcher.Run();
});

 thread.SetApartmentState(ApartmentState.STA);
 thread.Start();
}

【讨论】:

    【解决方案2】:

    我通常做的是让每个线程收集它的数据,BeginInvoke 自身到 GUI 线程,然后等待 AutoResetEvent/Semaphore。 GUI线程获取消息并显示表单/来自线程实例的数据。通常的组件回调(在 GUI 线程上下文中)使用来自用户/其他的附加数据加载线程成员,然后可能当关闭用户输入表单或单击 OK 按钮时,发出事件/sema 信号。然后工作线程继续运行,并加载了额外的用户数据。

    您不必 BeginInvoke 线程对象 - 如果需要,您可以发布其他一些“ThreadComms”对象,其中仅包含成员数据和要发出信号的事件。

    这基本上是一种可行的解决方案,毫无疑问还有其他解决方案。如果您有三个线程,有时可能会有点混乱,因为可能随时弹出三个用户输入表单,(令人讨厌的是,当用户填写一半时,会弹出来自 thread/s 2/3 的新表单来自线程 1) 的表单。

    你可以只调用 Invoke(),但如果可以的话,我会尽量避免直接的、同步的线程间通信。 Invoke() 和模态表单可以解决用户忙于填写时弹出新表单的问题。也许您可以尝试一下?

    【讨论】:

      猜你喜欢
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多