Problemumgehung: "Der aufrufende Thread muss STA sein."

Ich weiß, dass es zu diesem Thema einige Antworten auf SO gibt, aber ich kann keine der Lösungen für mich zum Laufen bringen. Ich versuche, ein neues Fenster von einem ICommand aus zu öffnen, der aus einer Datenvorlage heraus abgefeuert wurde. Beide der folgenden geben den oben genannten Fehlerwenn das neue Fenster instanziiert wird (in "new MessageWindowP"):

Verwenden von TPL / FromCurrentSynchronizationContext Update: funktioniert

<code>public class ChatUserCommand : ICommand
{
    public void Execute(object sender)
    {
        if (sender is UserC)
        {
            var user = (UserC)sender;
            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();                  
            Task.Factory.StartNew(new Action<object>(CreateMessageWindow), user,CancellationToken.None, TaskCreationOptions.None,scheduler);         
        }
    }

    private void CreateMessageWindow(object o)
    {
        var user = (UserC)o;
        var messageP = new MessageWindowP();
        messageP.ViewModel.Participants.Add(user);
        messageP.View.Show();
    }
}
</code>

Verwenden von ThreadStart: Update: nicht empfohlen, siehe Jon Antwort

<code>public class ChatUserCommand : ICommand
{
    public void Execute(object sender)
    {
        if (sender is UserC)
        {
            var user = (UserC)sender;

            var t = new ParameterizedThreadStart(CreateMessageWindow);
            var thread = new Thread(t);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start(sender);           
        }
    }

    private void CreateMessageWindow(object o)
    {
        var user = (UserC)o;
        var messageP = new MessageWindowP();
        messageP.ViewModel.Participants.Add(user);
        messageP.View.Show();
    }
}
</code>

Vielen Dank

BEARBEITEN. Anhand der bisherigen Antworten möchte ich darauf hinweisen, dass ich BeginInvoke auch auf dem aktuellen Dispatcher ausprobiert und den Code in der ursprünglichen Methode ausgeführt habe (so hat der Code begonnen). Siehe unten:

BeginInvoke Update: nicht empfohlen, siehe Jon Antwort

<code>public class ChatUserCommand : ICommand
{
    public void Execute(object sender)
    {
        if (sender is UserC)
        {
            var user = (UserC)sender;
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action<object>(CreateMessageWindow), sender);       
        }
    }

    private void CreateMessageWindow(object o)
    {
        var user = (UserC)o;
        var messageP = new MessageWindowP();
        messageP.ViewModel.Participants.Add(user);
        messageP.View.Show();
    }
}
</code>

Im selben Thread Update: Funktioniert, wenn Sie sich bereits in einem UI-Thread befinden

<code>public class ChatUserCommand : ICommand
{
    public void Execute(object sender)
    {
        if (sender is UserC)
        {
            var user = (UserC)sender;
            var messageP = new MessageWindowP();
            messageP.ViewModel.Participants.Add(user);
            messageP.View.Show();    
        }
    }

}
</code>

BeginInvoke unter Bezugnahme auf den Dispatcher des ersten / Hauptfensters Update: funktioniert

<code> public void Execute(object sender)
   {
       if (sender is UserC)
       {
            var user = (UserC)sender;
                    GeneralManager.MainDispatcher.BeginInvoke(
                               DispatcherPriority.Normal,
                               new Action(() => this.CreateMessageWindow(user)));      
        }
    }
</code>

Dabei ist GeneralManager.MainDispatcher ein Verweis auf den Dispatcher des ersten von mir erstellten Fensters:

<code>     [somewhere far far away]
        mainP = new MainP();
        MainDispatcher = mainP.View.Dispatcher;
</code>

Ich bin ratlos.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage