Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if method is async at runtime

I have a legacy project that has hundreds of method signatures for a Winforms event. Obviously the current ones I don't want to go and do BeginInvoke/EndInvoke on because this will cause UI cross threading issues.

However I have need (because of deadlocks) to be able to mark these signatures as async to handle some async commands that we have to be able to do. No other way results in anything other than a deadlock.

I can successfully call the event with BeginInvoke and it works perfectly and asyncs properly etc. However that breaks it out into another thread and breaks the old implementations that we don't want to have to go through and make async and Invoke aware.

So I was investigating using the event.GetInvokationList() and looping through and calling each separately. If the method was async, then begin/end invoke. Otherwise call it straight up on the UI thread.

My only problem is that I can't find any way through reflection to tell if the method signature is async or not.

Anyone know how to figure out if a method is async or not from the MethodInfo or something else from GetInvokationList() values?

Thanks!

like image 773
James Hancock Avatar asked Nov 01 '12 18:11

James Hancock


2 Answers

if you are using .net 4.5, try "AsyncStateMachineAttribute". http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.asyncstatemachineattribute.aspx

like image 121
MVarman Avatar answered Jan 02 '23 22:01

MVarman


MVarman's answer works for OP, but has a potential risk because AsyncStateMachineAttribute can be added manually. To make the check more robust, verify if the state machine is compiler generated.

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

For .NET core app, use

public static bool IsAsync(this MethodInfo m)
{
    return m?
        .GetCustomAttribute<AsyncStateMachineAttribute>()?
        .StateMachineType?
        .GetTypeInfo()
        .GetCustomAttribute<CompilerGeneratedAttribute>()
        != null;
}
like image 26
Cheng Chen Avatar answered Jan 02 '23 21:01

Cheng Chen