Domanda

Nel mio WPF applicazione che comunicare in modo asincrono con un server. La richiamata non sarà quindi essere eseguito nel thread UI, e come ho bisogno di fare alcune cose non ci WPF (creare l'oggetto InkPresenter) ho bisogno di essere eseguito sul thread dell'interfaccia utente. Beh, in realtà il requisito è che viene eseguito su un thread con la modalità appartamento STA. Ho cercato di creare un nuovo thread con modalità STA, ma il risultato è stato che il thread UI non potrebbe accedere al InkPresenter come è stato "di proprietà di un thread diverso".

Quello che voglio fare nella callback è quello di utilizzare il Dispatcher a Invoke mia funzione che richiede STA. Questo suona come il giusto approccio? Lo faccio ora, ma non riesce ancora. Nella mia funzione di callback ho innescare la seguente funzione, che ora cerca di assicurare che la indirizzato funzione viene eseguito sul thread dell'interfaccia utente.

private void UpdateAnnotationsForCurrentFrameCollection()
{
    if (Dispatcher.CurrentDispatcher.CheckAccess())
    {
        DoSomethingIncludingInkPresenter();
    }
    else
    {
        Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
           new Action(DoSomethingIncludingInkPresenter));
    }
}

private void DoSomethingIncludingInkPresenter()
{
    var inkPresenter = XamlReader.Parse(_someXamlString) as InkPresenter;
    // Do something with the inkPresenter.. 
}

Come si può vedere dal campione che uso CheckAccess () per garantire che invoco solo la funzione se non è già eseguito sul thread dell'interfaccia utente. Quando il mio callback chiama questa funzione CheckAccess () è sempre vero, ma è Dispatcher.CurrentDispatcher.Thread.ApartmentState MTA. Perché? Ho provato a rimuovere CheckAccess () e sempre facendo Invoke, ma l'ApartmentState rimane MTA, e la creazione del InkPresenter fallisce.

Qualcuno può spiegare che cosa sto facendo male qui? Ho il Dispatcher sbagliato o qualcosa del genere? È questo l'approccio giusto per far sì che qualcosa viene eseguito sul thread UI?

È stato utile?

Soluzione

Penso che si sta confondendo 2 Requisiti. WinForms e WPF filoni principali sono assegnati STA per consentire chiamate COM (e potevano essere avvengono all'interno dei controlli).

Il problema sembra essere il classico "l'interfaccia utente non è thread-safe" questione, e dovrebbe essere risolto con l'invio delle parti che toccano l'interfaccia utente.

Ma non si deve chiamare CheckAccess sul CurrentDispatche ma sul vostro obiettivo:
 someControl.Dispatcher.CheckAccess

Altri suggerimenti

Credo che il problema è che si sta utilizzando il torto Dispatcher. Uno del metodo provato e vero che ho usato è quello di passare il Dispatcher del controllo in cui il codice viene eseguito.

private void SomeMethod(Dispatcher dispatcher)
{
  DoOtherThingsThatCanDoMTA();

  dispatcher.Invoke(new Action(()=>
  {
    DoSomethingThatRequiresSTA();
  }));
}

Se in qualche modo non è possibile far passare il Dispatcher è possibile esporre in una proprietà o qualsiasi altro metodo. Mi auguro che aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top