Как определить, является ли метод async во время выполнения

У меня есть устаревший проект, который имеет сотни сигнатур методов для события Winforms. Очевидно, что текущие я не хочу идти и делать BeginInvoke/EndInvoke, потому что это вызовет проблемы с перекрестным потоком UI.

однако мне нужно (из-за тупиков), чтобы иметь возможность отмечать эти подписи как асинхронные для обработки некоторых асинхронных команд, которые мы должны иметь возможность делать. Другого пути нет результатов в тупик.

Я могу успешно вызвать событие с BeginInvoke и он отлично работает и asyncs правильно и т. д. Однако это разбивает его на другой поток и разбивает старые реализации, которые мы не хотим проходить и делать асинхронными и вызывать.

поэтому я расследовал использование события.GetInvokationList () и цикл и вызов каждого отдельно. Если метод был асинхронным,то begin / end invoke. В противном случае вызовите его прямо в потоке UI.

моя единственная проблема в том, что я не могу найти любой способ через отражение сказать, является ли подпись метода асинхронной или нет.

кто-нибудь знает, как выяснить, является ли метод асинхронным или нет из MethodInfo или что-то еще из значений GetInvokationList ()?

спасибо!

3 ответов


Если вы используете .net 4.5, попробуйте "AsyncStateMachineAttribute". http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.asyncstatemachineattribute.aspx


ответ MVarman работает для OP, но имеет потенциальный риск, потому что AsyncStateMachineAttribute можно добавить вручную. Чтобы сделать проверку более надежной, проверьте, сгенерирована ли государственная машина компилятором.

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 core используйте

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

вы не можете обнаружить его, и вы не должны. Методы, помеченные как асинхронные, фактически ничем не отличаются от любых других синхронных методов. Вы должны регулярно вызывать их.

кроме того, Begin/EndInvoke должны решить проблему маршалинга вызовов в другие потоки. Если вам требуется это конкретное знание, т. е. вы не знаете, должен ли метод выполняться в этом потоке, вы должны использовать свои собственные специальные атрибуты для таких методов, а не ключевое слово async, поскольку они в основном не смешиваются вместе.