2015-09-30 44 views
6

Ho riscontrato un problema con l'utilizzo async/await nella mia applicazione aggiuntiva, ho un riquadro attività personalizzato e l'utente può scaricare alcuni dati con esso, quindi sono problemi:Funzionamento asincrono/atteso non corretto, eventi Excel nel componente aggiuntivo Livello applicazione Excel

  1. Dopo l'operazione attesa completata il controllo non viene restituito al contesto di esecuzione precedente. Ho creato un esempio con i moduli di Windows e ho incollato lo stesso metodo in attesa e funziona bene - Posso usare i controlli del modulo dopo l'operazione, ma non nel componente aggiuntivo, devo richiamare il riquadro delle attività personalizzate Invoca il metodo. Esempio semplice:

    private void SearchPaneButton_Click(object sender, EventArgs e) 
    { 
        Search(); 
    } 
    
    private async void Search() 
    { 
        var searchText = SearchTextBox.Text; 
        SearchPaneButton.Text = "Loading…"; 
        var data = await new DataServiceClient().GetDataAsync(searchText); 
        this.Invoke((MethodInvoker)(() => 
        { 
         SearchPaneButton.Text = "Search"; 
         ToggleWorkbookEvents(); 
        })); 
    } 
    
  2. Nel mio add-in ho bisogno di gestire alcuni eventi - foglio di lavoro è cambiato, foglio di lavoro attivato/disattivato, ma questi eventi scompaiono e non viene licenziato dopo l'operazione attendere e devo usare qualcosa di simile "toggiando" (rimuovi + aggiungi) eventi dopo ogni atteso usando. Semplice esempio:

    private void ToggleWorkbookEvents() 
    { 
        var excel = Globals.BPNAddIn.Application; 
        //need to ensure event will not be set twice 
        excel.SheetActivate -= CheckSheetForData; 
        excel.SheetActivate += CheckSheetForData; 
        if (excel.ActiveWorkbook != null) 
        { 
         var activeSheet = Globals.BPNAddIn.GetActiveWorksheet(); 
         //need to ensure event will not be set twice 
         activeSheet.Change -= Worksheet_Changed; 
         activeSheet.Change += Worksheet_Changed; 
        } 
    } 
    

Così forse quadro VSTO non può supportare le nuove funzionalità (come asincrona attendono) delle ultime versioni di .NET Framework?

+1

Le domande StackOverflow devono avere il codice associato. Si prega di modificare con maggiori dettagli in modo che possiamo provare ad aiutare i vostri problemi reali. – SpaceSteak

+0

@SpaceSteak Ho aggiunto alcuni esempi di codice, grazie –

+0

Perché non stai aspettando su 'Cerca'? –

risposta

11

Questo è un problema di vecchia data con i plug-in di Office: non forniscono uno SynchronizationContext.

Come menzionato sul mio blog, è possibile aggirare il problema con ensuring you have a proper SynchronizationContext. Questo è un po 'hacky, ma funziona:

private async void SearchPaneButton_Click(object sender, EventArgs e) 
{ 
    if (SynchronizationContext.Current == null) 
    SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext()); 
    await SearchAsync(); 
} 

private async Task SearchAsync() 
{ 
    var searchText = SearchTextBox.Text; 
    SearchPaneButton.Text = "Loading…"; 
    var data = await new DataServiceClient().GetDataAsync(searchText); 
    SearchPaneButton.Text = "Search"; 
    ToggleWorkbookEvents(); 
} 

Per quanto riguarda il problema "eventi non girevoli" va, non ho idea.

+0

Perché lo consideri un po 'hacky? –

+0

grazie, come ho capito, lo sfondo non risolve il mio problema? Posso dividere il metodo 'Search' sugli eventi di background worker (invece di async/await) e usare la richiesta sincrona' GetData', quindi otterrò l'eccezione del thread? –

+2

@JeremyThompson: Perché il tuo codice deve fare qualcosa che il framework * dovrebbe * fare non solo qui, ma ovunque chiami il tuo codice. :/ –