Jes*_*ica 6 c# json asynchronous async-await .net-core
我正在使用 .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
}
]
Run Code Online (Sandbox Code Playgroud)
我不希望这些结果被包装在这个“异步”包装器中。
在保持方法异步的同时,如何返回任务结果,而不是包含任务结果的对象?
我没有使用的原因有两个.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;
}
Run Code Online (Sandbox Code Playgroud)
你的Select回报IEnumerable<Task>(因为它传递了一个async函数);您可以使用Task.WhenAll等待它们全部完成,然后打开结果:
[HttpGet]
public async Task<object> Get(string someParameter)
{
//Do stuff
var things = BuildACollectionOfItems();
var results = await Task.WhenAll(things
.Select(x => x.IrrelevantThing)
.OrderBy(x => x.SomethingIrrelevant)
.Select(async x => new
{
x.Id,
SomeProperty = await GetSomeProperty(x.Id)
}));
return new
{
Results = ((IEnumerable<object>) results),
SomeIrrelevantThing = someIrrelevantThing
};
}
Run Code Online (Sandbox Code Playgroud)