【问题标题】:open new window as STAThread以 STAThread 身份打开新窗口
【发布时间】:2018-06-08 09:45:13
【问题描述】:

我正在使用BackGroundWorker 访问一些数据并读取它。但是我需要在读取数据的代码中打开一个新的 wpf 窗口。 (synchronous)

执行此操作时出现错误。

我尝试在打开新窗口的函数上方添加[STAThread],但这不起作用。

打开新窗口的方法:

[STAThread]
int returnColumnStartSelection(string filePath)
{
    ColumnStartSelection css = new ColumnStartSelection(filePath);
    css.ShowDialog();
    return css.lineStart;
}

新窗口的入口点:

public ColumnStartSelection(string filePath)
{
    InitializeComponent();
    //
    this.Topmost = true;
    this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
}

【问题讨论】:

  • 不要在后台线程上创建和显示窗口。相反,使用主窗口的 Dispatcher 来调用显示辅助窗口的操作。
  • 您收到的异常消息告诉您,您正在尝试在工作线程上运行不是线程安全的代码。解决方法是尝试绕过消息,使用Application.Current.Dispatcher.BeginInvoke()来保证代码安全。
  • BGW 已创建,因此您不要必须从后台线程修改 UI。这就是进度事件的用途。 BGW 本身已经过时了,因为您可以使用 Tasks、Task.Run、async/await 和 IProgress<T> 来构建更复杂的异步方法
  • 顺便说一句,有几十个重复的问题。问题不在于 STAThread。 No 操作系统允许一个线程修改由另一个 线程创建的 UI。每个窗口没有“入口点”,只有一个处理所有窗口的消息泵。
  • 根本没有帮助我。不过谢谢。

标签: c# wpf multithreading backgroundworker


【解决方案1】:

我的解决方案:

我停止使用BackgroundWorker 并开始使用aysncawait。 对于我的STAThread 问题,我构建了一个新方法来创建一个新的 STAThread,而另一个线程只是等到值更改。

string selectTable(myDataTable dt)
{
    string column = null;
    Thread thread = new Thread(() =>
    {
        TableSelection ts = new TableSelection(dt);
        ts.ShowDialog();
        column = ts.column;
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();

    while (column == null)
    {
        Thread.Sleep(50);
    }
    try { thread.Abort(); } catch { }

    return column;
}

【讨论】:

    【解决方案2】:

    希望我能理解您的问题。如果没有,请随时纠正我。

    要从 BackgroundWorker_DoWork 方法中打开一个新窗口,您可以使用 cmets 中提到的 Dispatcher:

    Application.Current.Dispatcher.Invoke((Action)delegate
            {
                EmailEnter emailer = new EmailEnter("Transfer", employee);
                emailer.ShowDialog();
            });
    

    这是我的一些工作代码中的一个示例。员工变量是后台工作方法的本地变量,并作为参数发送到 EmailEnter 构造函数。然后使用 .ShowDialog() 打开窗口。

    我在 BackgroundWorker_DoWork 方法的末尾调用了它。

    在您的情况下,您希望将 EmailEnter 替换为 ColumnStartSelection 并将您的 filePath 变量传递给它。

    如果您想让我澄清任何事情,请告诉我。

    【讨论】:

      猜你喜欢
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 2019-04-22
      相关资源
      最近更新 更多