WPF Flexibility with error with STA thread

I want to show window, but i got an error "The calling thread must be STA, because many UI components require this". I found the sollution, but it's awfut to write this every time.

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

Are there any other sollutions? I put code of CustomMessageBoxBelow

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();
    }
}

Upvotes: 1

Views: 357

Answers (2)

Dean
Dean

Reputation: 751

Create a helper function and invoke the message box asynchronously on the UI thread:

static void ThreadSafeMessageBox(String text)
{
  Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(text)));
}

void Test()
{
  Task.Run(() => { ThreadSafeMessageBox("Hi!");});
}

Upvotes: 0

VMAtm
VMAtm

Reputation: 28355

As the WPF application is STA application, all the logic which deals with UI controls must run inside the context of the UI thread. This is exactly Dispatcher being used for - call the method into a UI simchronization context.

I agree that the code you've provided isn't nice, so you have to refactor it. I suggest you to create a method which will be run in background, returning the status of the operation, which can include the error codes and warnings.

The code could be something like this:

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();
    }
}

Other thing I wanted to say is that you probably should check the users input before it's being saved to the database, which could save their time.

Upvotes: 1

Related Questions