2012-11-01 39 views
5

我有一个遗留项目,有一个Winforms事件的数百个方法签名。显然,目前我不想去做BeginInvoke/EndInvoke,因为这会导致UI跨线程问题。如何确定方法在运行时是否异步

但是我需要(因为死锁)能够将这些签名标记为异步来处理一些我们必须能够执行的异步命令。除了僵局以外,没有别的办法可以产生任何结果。

我可以使用BeginInvoke成功调用事件,它可以完美工作,并可以正常使用异步处理等。但是,它会将其分解到另一个线程中,并打破我们不想经过的旧实现,并使异步和Invoke知道的。

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

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

任何人都知道如何从MethodInfo或其他GetInvokationList()值中找出方法是异步还是异步?

谢谢!

回答

0

你无法检测到,也不应该。标有异步的方法实际上与其他同步方法没有区别。你应该定期调用它们。

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

+0

好吧,我会创造我自己的属性。我想确定MS会添加到MethodInfo类中,告诉你方法是否标记为异步! –

+0

但它不一定。你也不知道方法是否使用产量,是吗?关键字异步是编译器的一个提示,它不会影响代码的执行。因此,即使你这样做,你也不知道它,这对你来说并不意味着很多。 –

+0

请注意,反编译器仍然可以检测是否使用异步标记了方法。 –

1

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; 
} 
相关问题