WPF 灵活性,但 STA 线程出错



我想显示窗口,但我收到错误"调用线程必须是 STA,因为许多 UI 组件都需要这个"。我找到了解决方案,但每次都写这个很糟糕。

Application.Current.Dispatcher.Invoke((Action) delegate
{
    msgBox =
        new CustomMessageBox(
            "Файл добавлен в базу, строки " + errors +
            " не были добавлены по причине неверных входных данных",
            "Уведомление");
    msgBox.Show();
});

还有其他解决方案吗?我把自定义消息框的代码放在下面

public partial class CustomMessageBox : Window
{
    public CustomMessageBox()
    {
        InitializeComponent();
    }
    public CustomMessageBox(string text, string title)
    {
        InitializeComponent();
        Title = title;
        TextBlock.Text = text;
    }
    private void OkBtn_OnClick(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}

由于 WPF 应用程序STA应用程序,因此处理 UI 控件的所有逻辑都必须在 UI 线程的上下文中运行。这正是用于Dispatcher - 将该方法调用到 UI 同步上下文中。

我同意您提供的代码不好,因此您必须重构它。我建议您创建一个将在后台运行的方法,返回操作的状态,其中可以包括错误代码和警告。

代码可能是这样的:

async void btnSave_Click(object sender, EventArgs e)
{
    // get string result of the operation
    var result = await Task.Run(() => SaveTheData());
    if (result != "OK")
    {
        msgBox = new CustomMessageBox(
                    "Файл добавлен в базу, строки " + result +
                    " не были добавлены по причине неверных входных данных",
                    "Уведомление");
        msgBox.Show();
    }
}

我想说的另一件事是,您可能应该在将用户输入保存到数据库之前检查用户输入,这可以节省他们的时间。

创建一个帮助程序函数并在 UI 线程上异步调用消息框:

static void ThreadSafeMessageBox(String text)
{
  Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(text)));
}
void Test()
{
  Task.Run(() => { ThreadSafeMessageBox("Hi!");});
}

最新更新