„Wątek wywołujący musi być obejściem STA”

Wiem, że jest kilka odpowiedzi na ten temat na temat SO, ale nie mogę znaleźć żadnego rozwiązania, które działa dla mnie. Próbuję otworzyć nowe okno z ICommandu wystrzelonego z tablicy danych. Oba poniższe podają wyżej wspomniany błądgdy zostanie utworzone nowe okno (w ramach „nowej wiadomościWindowP”):

Korzystanie z TPL / FromCurrentSynchronizationContext Aktualizacja: działa

<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>

Używanie wątku: Aktualizacja: niezalecana, patrz odpowiedź Jona

<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>

Dzięki

EDYTOWAĆ. Opierając się na dotychczasowych odpowiedziach, chciałbym podkreślić, że wypróbowałem też BeginInvoke na bieżącym programie rozsyłającym, a także wykonałem kod w oryginalnej metodzie (w ten sposób kod został uruchomiony). Zobacz poniżej:

BeginInvoke Aktualizacja: niezalecane patrz odpowiedź Jona

<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>

W tym samym wątku Aktualizacja: działa, jeśli jesteś już w wątku interfejsu użytkownika

<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, używając odwołania do dispatchera pierwszego / głównego okna Aktualizacja: działa

<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>

gdzie GeneralManager.MainDispatcher jest odwołaniem do Dyspozytora pierwszego okna, które tworzę:

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

Jestem ze stratą.

questionAnswers(3)

yourAnswerToTheQuestion