C#如何通过反射判断一个方法是否为async/await?例如classFoo{publicasyncTaskBar(){awaitTask.Delay(500);如果我们反思这个类和方法,我如何确定这是一个真正的async/await方法,而不仅仅是一个恰好返回任务的方法?classFoo{publicTaskBar(){returnTask.Delay(500);在我的代码副本中,异步方法的MethodInfo在CustomAttributes属性中包含以下内容:而普通方法的MethodInfo在其CustomAttributes属性中不包含任何项目。似乎应该在异步方法而不是标准方法上可靠地找到AsyncStateMachineAttribute。编辑:事实上,该页面甚至在示例中包含以下内容!如以下示例所示,您可以确定一个方法是否标记有Async(VisualBasic)或async(C#Reference)修饰符。在此示例中,IsAsyncMethod执行以下步骤:privatestaticboolIsAsyncMethod(TypeclassType,stringmethodName){//获取具有指定名称的方法。MethodInfo方法=classType.GetMethod(methodName);输入attType=typeof(AsyncStateMachineAttribute);//获取方法的自定义属性。//返回的值包含StateMachineType属性。//如果该方法的属性不存在,则返回Null。varattrib=(AsyncStateMachineAttribute)method.GetCustomAttribute(attType);返回(属性!=null);这是两个方法的示例,我想问您为什么认为应该区别对待它们:publicstaticasyncTaskM1(intvalue){awaitTask.Delay(20000);返回值;}publicstaticTaskM2(intvalue){returnTask.Delay(20000).ContinueWith(_=>value);在手动wave中,它们都具有完全相同的运行时行为-它们在20秒内什么都不做(并且线程在这段时间内不保留)然后它们运行一个小代理,它只将最初传递给方法的值传回。但是,您会因为我选择使用编译器来隐藏一些管道而完全不同地对待其中一个吗?Damien_The_Unbeliever提出了一个有趣的挑战。我认为检查AsyncStateMachineAttribute不是一个合适的解决方案。最初的问题不应该是该方法是否异步。相反,它应该是它是否可以等待。如果您在返回类型上检查方法GetAwaiter(),达米恩答案中的两个方法示例都将返回true。但是,只有使用AsyncStateMachineAttribute标记为异步的方法才会在自定义属性集合中包含AsyncStateMachineAttribute。如果您想使用MethodInfo.Invoke()来调用该方法,并且您可能提前知道是否需要向消息代理注册该方法,那么了解它是否可接受很重要。varisAwaitable=_methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter))!=null;对象结果=空;if(isAwaitable){result=await(dynamic)_methodInfo.Invoke(_instance,_parameterArray);}else{结果=_methodInfo.Invoke(_instance,_parameterArray);编辑:检查MethodInfo的返回类型是个好主意。这是我修改后的代码。以上是C#学习教程:如何通过反射判断一个C#方法是否异步/等待?如果分享的内容对你有用,需要进一步了解C#学习教程,希望你多多关注——varisAwaitable=_methodInfo.ReturnType.GetMethod(nameof(Task.GetAwaiter))!=null;对象invokeResult=null;如果(isAwaitable){如果(_methodInfo.ReturnType.IsGenericType){invokeResult=(object)await(dynamic)_methodInfo.Invoke(_instance,arguments);}else{await(Task)_methodInfo.Invoke(_instance,arguments);}}else{if(_methodInfo.ReturnType==typeof(void)){_methodInfo.Invoke(_instance,arguments);}else{invokeResult=_methodInfo.Invoke(_instance,arguments);}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
