Il seguente codice è una semplificazione di un codice in un'applicazione reale. Il problema di seguito è che verrà eseguito un lungo lavoro nel thread dell'interfaccia utente, anziché un thread in background.Come ottenere un'attività NON da eseguire sul thread dell'interfaccia utente
void Do()
{
Debug.Assert(this.Dispatcher.CheckAccess() == true);
Task.Factory.StartNew(ShortUIWork, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
void ShortUIWork()
{
Debug.Assert(this.Dispatcher.CheckAccess() == true);
Task.Factory.StartNew(LongWork, TaskCreationOptions.LongRunning);
}
void LongWork()
{
Debug.Assert(this.Dispatcher.CheckAccess() == false);
Thread.Sleep(1000);
}
Così Do() viene chiamato normalmente dal contesto dell'interfaccia utente. E così anche ShortUIWork, come definito da TaskScheduler. Tuttavia, LongWork termina anche nel thread dell'interfaccia utente, che, ovviamente, blocca l'interfaccia utente.
Come assicurarsi che un'attività non venga eseguita nel thread dell'interfaccia utente?
'tasks' creare un thread che * non * eseguito su interfaccia utente per definizione. Sei sicuro che 'LongWork' blocca il thread dell'interfaccia utente? – Tigran
@Tigran: TPL utilizza thread di background per impostazione predefinita, non per definizione. –
Il codice che non ripro il problema non aiuta. Un motivo comune per un comportamento come questo è una classe wrapper per un componente COM. COM mantiene gli oggetti delle classi che si pubblicizzano per non supportare alcun tipo di threading sicuro eseguendo automaticamente il marshalling di tutte le chiamate al thread che li ha creati. –