c# - 等待动态获取错误“System.ValueType”不包含“GetAwaiter”的定义
问题描述
get error 'System.ValueType' does not contain a definition for 'GetAwaiter' 代码见github https://github.com/wangronghua/DynamicIssue 分支master是错误的,branch ok是对的,区别是代理类被移动了到控制台项目。这是代码。
控制台类库
class Program
{
static async Task Main(string[] args)
{
var items = (await ProxyDecorator2<IPersonService, PersonService>.Create().GetPartAsync(x => new { x.ID, x.Name }, x => x.ID == 1));
foreach (var item in items)
{
Console.WriteLine(item.ID);
Console.WriteLine(item.Name);
}
Console.WriteLine("结束");
}
}
二级图书馆
public class PersonService: IPersonService
{
public ValueTask<List<TResult>> GetPartAsync<TResult>(Func<Person, TResult> selresult, Func<Person, bool> predicate)
{
return new ValueTask<List<TResult>>(dataSource.Where(predicate).Select(selresult).ToList());
}
private static List<Person> dataSource=new List<Person>
{
new Person{ ID = 1,Name = "张三"},
new Person{ ID = 2,Name = "李四"}
};
}
public interface IPersonService
{
ValueTask<List<TResult>> GetPartAsync<TResult>(Func<Person, TResult> selresult, Func<Person, bool> predicate);
}
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ProxyDecorator2<T, TClass> : DispatchProxy where T : class where TClass : T, new()
{
protected T _decorated;
public static T Create()
{
var proxy = Create<T, ProxyDecorator2<T, TClass>>();
var proxyReal = proxy as ProxyDecorator2<T, TClass>;
if (proxyReal == null) throw new Exception("proxyReal报错");
proxyReal._decorated = new TClass();
return proxy;
}
private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args)
{
dynamic dy = targetMethod.Invoke(_decorated, args);
var x = await dy;
return dy;
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
return InvokeCoore(targetMethod, args).Result;
}
}
将proxydecorator2移至控制台类库即可正常运行。
更新1
嗯,我有个事务注入的需求,已经完成了,所以需要await任务
private async Task<object> InvokeCoore(MethodInfo targetMethod, object[] args)
{
dynamic dy = targetMethod.Invoke(_decorated, args);
var x = await dy;
return dy;
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
//Open transaction
var result = InvokeCoore(targetMethod, args).Result;
//commit transaction
return result;
}
如果不等待,业务代码会在执行完成之前执行commit事务,所以有问题。或者什么是满足我需求的好方法?
更新2
更神奇的是,调用的时候不用匿名类也能正常运行
var items = (await ProxyDecorator2<IPersonService, PersonService>.Create().GetPartAsync(x => new AA { ID = x.ID, Name= x.Name }, x => x.ID == 1));
public class AA
{
public int ID { get; set; }
public string Name { get; set; }
}
解决方案
我冒昧地克隆了您的代码。
问题出在以下几行:
dynamic dy = targetMethod.Invoke(_decorated, args);
var x = await dy;
更改dynamic
为var
,你会得到一个错误,说object
是不可等待的。
所以要修复它,请更改您的代码
private object InvokeCoore(MethodInfo targetMethod, object[] args)
{
var dy = targetMethod.Invoke(_decorated, args);
return dy;
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
return InvokeCoore(targetMethod, args);
}
或者,如果您不想更改 InvokeCoore 的签名:
private Task<object> InvokeCoore(MethodInfo targetMethod, object[] args)
{
var dy = targetMethod.Invoke(_decorated, args);
return Task.FromResult(dy);
}
更新:我试图比较代码,看看编译器是否足够聪明,可以确定你根本不需要 Async,所以它只是没有编译成状态机。但事实并非如此。查看 Sharplab 上的代码似乎差别不大。
推荐阅读
- java - 更改相机设置时形状消失
- ios - 下面的代码对于分离签名工作得很好!如何获得附加签名?
- python - 如何在 python 中翻译此代码以使其更具可读性?
- php - Laravel如何与全名连接名字中间名首字母姓氏
- django - Django:如果查询集为空,则签入模板
- java - Java - 线程计算更慢
- ios - 是否可以在 ios 上使用 firebase 更新已发送的通知?
- java - 如何减少自定义反序列化器中的 if 数量
- python - Tkinter 无法使用命令更改对象(按钮)颜色我错过了什么?
- c++ - 我如何将定义(#define SOME_DEFINE)作为函数的参数传递?