2012-11-01 20 views
5

Ich habe ein Legacy-Projekt mit hunderten von Methodensignaturen für ein Winforms-Ereignis. Offensichtlich möchte ich die aktuellen nicht gehen und BeginInvoke/EndInvoke ausführen, da dies Probleme beim Cross Threading der Benutzeroberfläche verursachen wird.So ermitteln Sie, ob die Methode zur Laufzeit asynchron ist

Allerdings muss ich (wegen Deadlocks) in der Lage sein, diese Signaturen als async zu markieren, um einige asynchrone Befehle zu bearbeiten, die wir ausführen können. Kein anderer Weg führt zu etwas anderem als einem Deadlock.

Ich kann das Ereignis erfolgreich mit BeginInvoke aufrufen und es funktioniert perfekt und asyncs richtig usw. Allerdings bricht es in einem anderen Thread und bricht die alten Implementierungen, die wir nicht durchlaufen und Async und Invoke machen müssen bewusst.

Also untersuchte ich mit der event.GetInvokationList() und durchschleifen und aufrufen jeweils getrennt. Wenn die Methode asynchron war, dann starte/beende den Aufruf. Ansonsten rufe es direkt auf dem UI-Thread auf.

Mein einziges Problem ist, dass ich keinen Weg durch Reflexion finden kann, um festzustellen, ob die Methodensignatur asynchron ist oder nicht.

Wer weiß, wie man herausfinden kann, ob eine Methode asynchron oder nicht von der MethodInfo oder etwas anderes von GetInvokationList() - Werten ist?

Danke!

Antwort

3

Wenn Sie .net 4.5 verwenden, versuchen Sie "AsyncStateMachineAttribute".

+0

Funktioniert perfekt! Vielen Dank! –

0

Sie können es nicht erkennen, oder Sie sollten es nicht tun. Mit async markierte Methoden unterscheiden sich tatsächlich nicht von anderen synchronen Methoden. Sie sollten sie regelmäßig aufrufen.

Außerdem soll Begin/EndInvoke das Problem der Marshalling Aufrufe an andere Threads lösen. Wenn Sie dieses spezielle Wissen benötigen, d. H. Sie wissen nicht, ob die Methode in diesem Thread ausgeführt werden soll, sollten Sie Ihre eigenen speziellen Attribute für solche Methoden anstelle des async-Schlüsselworts verwenden, da sie im Grunde nicht miteinander vermischt sind.

+0

Ok, ich werde mein eigenes Attribut erstellen. Ich hätte sicher gedacht, dass MS der MethodInfo-Klasse hinzugefügt hätte, um Ihnen zu sagen, ob die Methode als asynchron markiert wurde oder nicht! –

+0

Aber es muss nicht. Sie wissen auch nicht, ob die Methode im Inneren verwendet, oder? Das Schlüsselwort async ist ein Hinweis für den Compiler und hat keinen Einfluss auf die Ausführung des Codes. Daher kannst du nichts darüber wissen, denn selbst wenn du es tust, bedeutet es dir nicht viel. –

+0

Beachten Sie, dass Decompiler weiterhin erkennen können, ob eine Methode mit Async markiert ist oder nicht. –

1

MVarmans Antwort funktioniert für OP, birgt aber ein potentielles Risiko, weil AsyncStateMachineAttribute manuell hinzugefügt werden kann. Um die Überprüfung robuster zu machen, überprüfen Sie, ob die Statusmaschine vom Compiler generiert wurde.

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; 
} 

Für .NET Kern App verwenden

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