2012-11-01 11 views
5

Mam starszego projektu, który ma setki podpisów metody dla zdarzenia WinForm. Oczywiście obecne, których nie chcę iść i włączam BeginInvoke/EndInvoke, ponieważ spowoduje to problemy z przekierowaniem interfejsu użytkownika.Jak ustalić, czy metoda jest asynchroniczna w czasie wykonywania

Jednak potrzebuję (z powodu zakleszczenia), aby móc oznaczyć te sygnatury jako asynchroniczne, aby obsłużyć niektóre polecenia asynchroniczne, które musimy wykonać. Żaden inny sposób nie prowadzi do niczego poza impasem.

Mogę z powodzeniem wywołać zdarzenie za pomocą BeginInvoke i działa idealnie i asynchronicznie poprawnie itd. Jednak powoduje to podzielenie go na inny wątek i łamie stare implementacje, których nie chcemy przechodzić i tworzyć asynchroniczne i wywoływać świadomy.

Tak więc badałem używając event.GetInvokationList() i przepuszczając je i wywołując osobno. Jeśli metoda była asynchroniczna, wywołaj metodę begin/end. W przeciwnym razie wywołaj go prosto w wątku UI.

Jedynym moim problemem jest to, że nie mogę znaleźć żadnej drogi przez odbicie, aby stwierdzić, czy sygnatura metody jest asynchroniczna, czy też nie.

Ktoś wie, jak dowiedzieć się, czy metoda jest asynchroniczna, czy nie z MethodInfo lub coś innego z wartości GetInvokationList()?

Dzięki!

Odpowiedz

0

Nie możesz tego wykryć, a nie powinieneś. Metody oznaczone asynchronicznie nie różnią się od innych metod synchronicznych. Powinieneś regularnie je wywoływać.

Ponadto Begin/EndInvoke mają rozwiązać problem przekazywania połączeń do innych wątków. Jeśli potrzebujesz tej konkretnej wiedzy, to znaczy nie wiesz, czy metoda ma być uruchomiona w tym wątku, powinieneś używać własnych specjalnych atrybutów na takich metodach, a nie asynchronicznego słowa kluczowego, ponieważ w zasadzie nie są one mieszane razem.

+0

Ok, będę tworzyć własne atrybut. Zrozumiałbym na pewno, że MS dodałoby do klasy MethodInfo, aby powiedzieć, czy metoda została oznaczona jako async, czy nie! –

+0

Ale to nie musi. Ty też nie wiesz, czy metoda wykorzystuje plon w środku, prawda? Asynchronizacja słów kluczowych jest wskazówką dla kompilatora, nie wpływa na wykonanie kodu. Dlatego nie możesz o tym wiedzieć, ponieważ nawet jeśli to robisz, nie znaczy to dla ciebie zbyt wiele. –

+0

Należy pamiętać, że dekompilatory wciąż mogą wykryć, czy dana metoda jest oznaczona asynchronicznie. –

1

Odpowiedź MVarmana działa na OP, ale ma potencjalne ryzyko, ponieważ AsyncStateMachineAttribute można dodać ręcznie. Aby sprawdzenie było bardziej niezawodne, sprawdź, czy komputer stanu jest generowany przez kompilator.

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

NET rdzenia aplikacji, użyj

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