如何确定方法在运行时是否异步

时间:2012-11-01 18:27:50

标签: winforms delegates async-await

我有一个遗留项目,其中包含数百个Winforms事件的方法签名。显然,当前我不想去做BeginInvoke / EndInvoke,因为这会导致UI交叉线程问题。

但是我需要(因为死锁)能够将这些签名标记为异步以处理我们必须能够执行的某些异步命令。除了僵局之外别无他法。

我可以使用BeginInvoke成功调用该事件,并且它可以正常工作并且正确运行asyncs等。但是这会将其分解为另一个线程并打破我们不希望经历的旧实现并使异步和Invoke意识到

所以我正在调查使用event.GetInvokationList()并循环并分别调用每个。如果方法是异步的,则开始/结束调用。否则,在UI线程上直接调用它。

我唯一的问题是我无法通过反射找到任何方法来判断方法签名是否异步。

任何人都知道如何根据MethodInfo或GetInvokationList()值中的其他方法判断方法是否异步?

谢谢!

3 个答案:

答案 0 :(得分:3)

如果您使用的是.net 4.5,请尝试“AsyncStateMachineAttribute”。 http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.asyncstatemachineattribute.aspx

答案 1 :(得分:2)

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核心应用程序,请使用

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

答案 2 :(得分:0)

您无法检测到它,也不应该检测到它。标记为异步的方法实际上与任何其他同步方法没有什么不同。你应该定期调用它们。

此外,Begin / EndInvoke应该解决编组调用其他线程的问题。如果您需要特定的知识,即您不知道该方法是否应该在此线程上运行,那么您应该在这些方法上使用您自己的特殊属性而不是async关键字,因为它们基本上没有混合在一起。