gpt4 book ai didi

c# - 等待动态获取错误 'System.ValueType'不包含 'GetAwaiter'的定义

转载 作者:行者123 更新时间:2023-12-02 08:28:07 25 4
gpt4 key购买 nike

出现错误“System.ValueType”不包含“GetAwaiter”的定义。代码见github https://github.com/wangronghua/DynamicIssuebranch 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

嗯,我有一个事务注入(inject)的需求,已经完成了,所以我需要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);
}

更新:我尝试比较代码,看看编译器是否足够聪明,可以发现您根本不需要异步,因此它只是没有编译成状态机。但事实并非如此。查看 Sharplab 上的代码,似乎差别很小。

关于c# - 等待动态获取错误 'System.ValueType'不包含 'GetAwaiter'的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59342806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com