Procedura: Gestire più thread nel codice gestito

Se si dispone di un'estensione VSPackage gestita che chiama metodi asincroni o dispone di operazioni che vengono eseguite su thread diversi dal thread dell'interfaccia utente di Visual Studio, è necessario seguire le linee guida riportate di seguito. È possibile mantenere reattivo il thread dell'interfaccia utente perché non è necessario attendere il completamento del lavoro in un altro thread. È possibile rendere il codice più efficiente, perché non sono disponibili thread aggiuntivi che prendono spazio nello stack ed è possibile renderlo più affidabile e più facile da sottoporsi a debug perché si evitano deadlock e codice che non risponde.

In generale, è possibile passare dal thread dell'interfaccia utente a un thread diverso o viceversa. Quando il metodo viene restituito, il thread corrente è il thread da cui è stato chiamato in origine.

Importante

Le linee guida seguenti usano le API nello spazio dei Microsoft.VisualStudio.Threading nomi , in particolare la classe JoinableTaskFactory . Le API in questo spazio dei nomi sono nuove in Visual Studio 2013 . È possibile ottenere un'istanza di JoinableTaskFactory dalla ThreadHelper proprietà ThreadHelper.JoinableTaskFactory .

Passare dal thread dell'interfaccia utente a un thread in background

  1. Se si usa il thread dell'interfaccia utente e si vuole eseguire operazioni asincrone su un thread in background, usare Task.Run() :

    await Task.Run(async delegate{
        // Now you're on a separate thread.
    });
    // Now you're back on the UI thread.
    
    
  2. Se si usa il thread dell'interfaccia utente e si vuole bloccare in modo sincrono mentre si esegue il lavoro su un thread in background, usare TaskScheduler la proprietà TaskScheduler.Default all'interno di Run :

    // using Microsoft.VisualStudio.Threading;
    ThreadHelper.JoinableTaskFactory.Run(async delegate {
        await TaskScheduler.Default;
        // You're now on a separate thread.
        DoSomethingSynchronous();
        await OrSomethingAsynchronous();
    });
    

Passare da un thread in background al thread dell'interfaccia utente

  1. Se si usa un thread in background e si vuole eseguire un'operazione nel thread dell'interfaccia utente, usare SwitchToMainThreadAsync :

    // Switch to main thread
    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
    

    È possibile usare il metodo SwitchToMainThreadAsync per passare al thread dell'interfaccia utente. Questo metodo invia un messaggio al thread dell'interfaccia utente con la continuazione del metodo asincrono corrente e comunica anche con il resto del framework di threading per impostare la priorità corretta ed evitare deadlock.

    Se il metodo del thread in background non è asincrono e non è possibile renderlo asincrono, è comunque possibile usare la sintassi per passare al thread dell'interfaccia utente tramite il wrapping del lavoro con , come await Run in questo esempio:

    ThreadHelper.JoinableTaskFactory.Run(async delegate {
        // Switch to main thread
        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
        // Do your work on the main thread here.
    });