美好的一天,
我正在努力获取自己的价值。但是我遇到的结果是System.Threading.Tasks.UnwrapPromise
1 [System.Threading.Tasks.VoidTaskResult]`
这是我的示例代码:
public string GetStatusName(int empId){
var status = Task.Run(async () =>
{
return await myRepo.GetStatus().Where(x=>x.EmpId == empId).Select(x => x.status).FirstOrDefaultAsync();
});
return status.ToString();
}
结果应该是状态的名称,但显示方式会有所不同。
我尝试在.Result()
中使用return status.Result().ToString()
,但是它锁定了UI线程,因此,获取一千条记录大约需要一分钟。
注意:给定的方法不应按照要求异步。因此我将Task.Run...
放入了我的方法中,以便能够从回购中创建异步请求
我在此代码内使用GetStatusName()
:
public async Task<IEnumerable<EmployeeDto>> GetAll(){
var employees = await getFromRepo.Employees();
return employees.Select(x=>new EmployeeDto{
...
Status = GetStatusName(x.EmpId)
...
}).GroupBy(x=>new{
x.EmployeeId
}).Select(x=>x.First)).ToList();
}
我尝试了此操作,以使GetStatusName
异步并尝试了以下代码:
return employees.Select(async x=>new EmployeeDto{
...
Status = await GetStatusName(x.EmpId)
...
}).GroupBy(x=>new{
x.EmployeeId
}).Select(x=>x.First)).ToList();
但是我在.GroupBy(...)
中遇到错误,说Anonymous Types
和类似Can't resolve symbol EmployeeId
请帮忙吗?
答案 0 :(得分:2)
给定的方法不应该按照要求异步。
我建议您更改要求并转到async
all the way。
在您的情况下,理想情况下,您希望通过在初始员工查找中包括员工状态来避免辅助数据库查找。 Entity Framework has built-in support for this,尽管似乎您的数据库架构可能首先需要做一些工作(即,为什么在单独的表中按员工ID索引状态名称?)。
由于该解决方案更为详细,所以现在暂时搁置它,然后看看第二好的解决方案。您需要执行辅助数据库查找,并且应该进行async
。这样的事情应该起作用:
public async Task<string> GetStatusNameAsync(int empId) {
return await myRepo.GetStatus().Where(x=>x.EmpId == empId).Select(x => x.status).FirstOrDefaultAsync().ConfigureAwait(false);
}
public async Task<IEnumerable<EmployeeDto>> GetAll(){
var employees = await getFromRepo.Employees();
var statuses = new List<string>();
foreach (var employee in employees)
statuses.Add(await GetStatusNameAsync(employee.EmpId));
return employees.Select((x, i) => new EmployeeDto {
...
Status = statuses[i],
...
}).GroupBy(x => new {
x.EmployeeId
}).Select(x=>x.First)).ToList();
}
我只建议将其作为临时解决方案,以等待更好的数据库架构和/或ORM映射。
答案 1 :(得分:0)
您可以像这样简化您的方法:
public async Task<string> GetStatusName(){
return await myRepo.GetStatus().Select(x => x.status).FirstOrDefaultAsync();
}
答案 2 :(得分:0)
避免混合同步和异步调用。
引用Async/Await - Best Practices in Asynchronous Programming
使方法完全异步
public Task<string> GetStatusNameAsync(int empId) {
return myRepo.GetStatus()
.Where(x => x.EmpId == empId)
.Select(x => x.status)
.FirstOrDefaultAsync();
}
等待它
public async Task<IEnumerable<EmployeeDto>> GetAll(){
var employees = await getFromRepo.Employees();
var tasks = employees
.GroupBy(_ => _.EmpId)
.Select(async x => new EmployeeDto {
Status = await GetStatusNameAsync(x.Key), //<--
//...
}).ToArray();
var results = await Task.WhenAll(tasks);
return results.ToList();
}