2012-11-01 14 views
5

Ho un progetto legacy con centinaia di firme dei metodi per un evento Winforms. Ovviamente quelli attuali non voglio andare a fare BeginInvoke/EndInvoke perché questo causerà problemi di threading dell'interfaccia utente.Come determinare se il metodo è asincrono in fase di esecuzione

Tuttavia ho bisogno (a causa di deadlock) di poter contrassegnare queste firme come asincrone per gestire alcuni comandi asincroni che dobbiamo essere in grado di fare. Nessun altro modo si traduce in qualcosa di diverso da un punto morto.

Posso chiamare correttamente l'evento con BeginInvoke e funziona perfettamente e async correttamente ecc. Tuttavia, questo lo spezza in un altro thread e interrompe le vecchie implementazioni che non vogliamo passare e rendere async e Invoke consapevole.

Quindi stavo investigando usando l'event.GetInvokationList() e collegandomi e chiamandoli separatamente. Se il metodo era asincrono, quindi inizio/fine invoca. Altrimenti chiamalo direttamente sul thread dell'interfaccia utente.

Il mio unico problema è che non riesco a trovare alcun modo attraverso il riflesso per dire se la firma del metodo è asincrona o meno.

Qualcuno sa come capire se un metodo è asincrono o meno da MethodInfo o qualcos'altro dai valori GetInvokationList()?

Grazie!

risposta

0

Non è possibile rilevare o non si dovrebbe. I metodi contrassegnati con async non sono in effetti diversi da altri metodi sincroni. Dovresti invocarli regolarmente.

Inoltre, Begin/EndInvoke dovrebbe risolvere il problema delle chiamate di marshalling ad altri thread. Se hai bisogno di quella particolare conoscenza, cioè non sai se il metodo dovrebbe essere eseguito su questo thread, dovresti usare i tuoi attributi speciali su tali metodi piuttosto che la parola chiave async poiché fondamentalmente non sono mescolati insieme.

+0

Ok, creerò la mia attributo. Avrei pensato che MS avrebbe aggiunto alla classe MethodInfo per dirti se il metodo era marcato asincrono o no! –

+0

Ma non è necessario. Inoltre non sai se il metodo usa la resa dentro, vero? Keyword async è un suggerimento per il compilatore, non influenza l'esecuzione del codice. Quindi, non puoi saperlo perché anche se lo fai, non significa molto per te. –

+0

Si noti che i decompilatori possono ancora rilevare se un metodo è contrassegnato o meno con async. –

1

La risposta di MVarman funziona per OP, ma presenta un rischio potenziale perché AsyncStateMachineAttribute può essere aggiunto manualmente. Per rendere il controllo più robusto, verificare se la macchina di stato è generata dal compilatore.

public static bool IsAsync(this MethodInfo m) 
{ 
    var stateMachineAttr = m.GetCustomAttribute<AsyncStateMachineAttribute>(); 
    if (stateMachineAttr != null) 
    { 
     var stateMachineType = stateMachineAttr.StateMachineType; 
     if (stateMachineType != null) 
     { 
      return stateMachineType.GetCustomAttribute<CompilerGeneratedAttribute>() != null; 
     } 
    } 
    return false; 
} 

Per .NET nucleo app, utilizzare

public static bool IsAsync(this MethodInfo m) 
{ 
    return m? 
     .GetCustomAttribute<AsyncStateMachineAttribute>()? 
     .StateMachineType? 
     .GetTypeInfo() 
     .GetCustomAttribute<CompilerGeneratedAttribute>() 
     != null; 
} 
Problemi correlati