I'm writing an API with .NET Core 3.1. This API has an asynchronous function called GetSomeProperty()
, which I use in an endpoint (called Get
).
When receiving the response from this endpoint, the results
properties are "moved down" one layer, and wrapped in metadata from the asynchronous method, like this:
"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
}
]
I don't want these results to be wrapped in this "asynchronous" wrapper.
While keeping the method asynchronous, how can I return the task result, instead of an object containing the task result?
There are two reasons why I haven't used .Result
:
.Result
is considered bad practice, as it can cause locks if the task hasn't yet completed.Here is the code (please bear in mind this has been significantly diluted and simplified for example purposes):
[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;
}
To return values from async functions using async-await from function with JavaScript, we return the resolve value of the promise. const getData = async () => { return await axios.
The behavior of async / await is similar to combining generators and promises. Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
An asynchronous function is any function that delivers its result asynchronously – for example, a callback-based function or a Promise-based function. An async function is defined via special syntax, involving the keywords async and await . It is also called async/await due to these two keywords.
Now, one condition is when we want to return void. We cannot use the await keyword when we want to return void from an asynchronous function. In the above example, CallProcess() is an asynchronous function and it's returning void.
Your Select
returns IEnumerable<Task>
(because it is passed an async
function); you can use Task.WhenAll
to wait for them all to complete, and unwrap the results:
[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
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With