我正在尝试编写一个使用OnMethodBoundaryAspect的属性。
public class MyValidationAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//Set Task result after validation is performed
if (invalid)
{
args.ReturnValue = Task.FromResult("blah");
args.YieldValue= Task.FromResult("blah");
}
}
}
OnEntry我正在验证一个实体,然后更新Yield和Return类型。应用方面的方法的签名是public async Task<Response<T>>
当我使用Task.Result在类上测试它时,该方法返回我对该属性的期望。但是,如果我等待该方法,该方法不会返回预期的数据。
e.g。
var resultSuccess = myClass.DoIt().Result;
var resultFail = await myClass.DoIt();
思考/建议?
答案 0 :(得分:1)
将方面应用于异步方法时,需要决定是将其应用于原始方法还是应用于编译器生成的基础状态机。
基本上,您的原始方法由C#编译器转换为初始化新的状态机结构,并且您的原始代码将移动到结构的private void MoveNext()
方法。
如果您想更改方法的返回值并立即退出,则应将方面应用于原始方法,设置args.ReturnValue,并将args.FlowBehavior设置为FlowBehavior.Return
。要将方面应用于原始方法集ApplyToStateMachine至false
。
[Serializable]
public class MyValidationAttribute : OnMethodBoundaryAspect
{
public MyValidationAttribute()
{
this.ApplyToStateMachine = false;
}
public override void OnEntry(MethodExecutionArgs args)
{
if (invalid)
{
args.ReturnValue = Task.FromResult("blah");
args.FlowBehavior = FlowBehavior.Return;
}
}
}
public class MyClass
{
[MyValidation]
public async Task<string> DoIt()
{
// ...
}
}
P.S。仅当与迭代器方法一起使用时,属性args.YieldValue才有意义。