我正在使用.NET Core 3.1编写一个API。该API具有一个异步函数,名为
当从此端点接收响应时,
GetSomeProperty()
,我在一个端点(称为Get
)中使用它。当从此端点接收响应时,
results
属性向下“移动”一层,并用异步方法的元数据包装,如下所示:"results": [
{
"result": {//actual result here}
"id": 1,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"creationOptions": 0,
"isFaulted": false
},
{
"result": {//actual result here}
"id": 2,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"creationOptions": 0,
"isFaulted": false
}
]
我不希望这些结果被包裹在这个“异步”包装器中。
保持方法异步的同时,我如何返回任务结果,而不是包含任务结果的对象?
我没有使用 .Result
的两个原因:
- 使用
.Result
被认为是不良做法,因为如果任务尚未完成,它可能会导致锁定。 - 我找不到放置它的位置。就我所知,它似乎没有适合的位置。
这是代码(请记住,这已经被大大简化和简化,仅供示例):
[HttpGet]
public async Task<object> Get(string someParameter)
{
//Do stuff
var things = BuildACollectionOfItems();
var results = things.Select(x => x.IrrelevantThing).OrderBy(x => x.SomethingIrrelevant).Select(async x =>
{
return new
{
x.Id,
SomeProperty = await GetSomeProperty(x.Id)
};
}).ToArray();
return new
{
Results = ((IEnumerable<object>) results),
SomeIrrelevantThing = someIrrelevantThing
};
}
private async Task<bool> GetSomeProperty(int id)
{
var somethingFromAServer = (await _thingProvider.GetThing()).TheProperty;
//Do stuff here
var thing = _context.Stuff.FirstOrDefault(x => x.Thing == somethingFromAServer);
//Do some more stuff
return thing.Stuff;
}
async
方法中使用后缀Async
:async Task<bool> GetSomePropertyAsync(int id)
。 - dymanoidthings.Select()
是可等待的吗?例如:var results = await things.Select(...)
结构上看起来Get()
本身并没有等待任何东西,而结果正在获取任务列表。 - Davidawait
,导致任务无法执行。建议检查一下那些被强制转换为object
类型的变量,因为它们可以引用任何东西,包括Task<object>
类型的对象。同时,也要检查一下你的var
变量所推断出的实际类型。 - Damien_The_Unbeliever.Select()
是IEnumerable
上的标准LINQ方法吗?如果是的话,那么这看起来非常有前途:https://dev59.com/qmUp5IYBdhLWcg3w669C 也许需要额外的一些步骤,但是想法是在返回整个结果之前等待所有任务完成。我现在没有测试它的方法,但是只需将该方法末尾的赋值更改为Results = Task.WhenAll(results)
可能就可以了。 - David