How does Taskint become an int?
Does an implicit conversion occur between Task<> and int?
Nope. This is just part of how async
/await
works.
Any method declared as async
has to have a return type of:
void
(avoid if possible)Task
(no result beyond notification of completion/failure)Task<T>
(for a logical result of typeT
in an async manner)
The compiler does all the appropriate wrapping. The point is that you're asynchronously returning urlContents.Length
- you can't make the method just return int
, as the actual method will return when it hits the first await
expression which hasn't already completed. So instead, it returns a Task<int>
which will complete when the async method itself completes.
Note that await
does the opposite - it unwraps a Task<T>
to a T
value, which is how this line works:
string urlContents = await getStringTask;
... but of course it unwraps it asynchronously, whereas just using Result
would block until the task had completed. (await
can unwrap other types which implement the awaitable pattern, but Task<T>
is the one you're likely to use most often.)
This dual wrapping/unwrapping is what allows async to be so composable. For example, I could write another async method which calls yours and doubles the result:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Or simply return await AccessTheWebAsync() * 2;
of course.)
Why return Taskint instead of int? (async & await)
Because async
keyword is just a syntactic sugar around a method which returns a task. That is its definition.
Under the hood, when the compiler encounters await
on the same method call, it will add complete asynchronous call and waiting for completion of the task. Therefore, compiler requires a Task<int>
to construct the code for you, the code that ultimately compiles.
Note that the code that follows await
is coded as task continuation on the task returned from the method. There is quite a lot of boilerplate if you tried to write it yourself. That is why async/await
keywords are so useful.
Return Taskint from int member C# best practice
You don't need async
at all.
Just create a normal method and call Task.FromResult()
to create a synchronously-resolved task with your result.
How to get the integer value returned in Task int format - Asp.net Core MVC - MediaTr
Probably the easiest way to unwrap the value returned by a Task
would be to use async
/await
.
Though, you'll want to shy away from async void
methods where possible as this results in a "fire and forget" method that cannot be awaited (this will potentially turn into a debugging nightmare as any exceptions will be lost to the void, etc.) -- so let's have the Register method return a Task
instead:
async public Task Register(PessoaViewModel pessoaViewModel)
{
var registerCommand = _mapper.Map<RegisterNewPessoaCommand>(pessoaViewModel);
var pessoaId = await Bus.SendCommand(registerCommand);
// use `pessoaId` as needed
}
If for some reason async
/await
is unavailable, the following option is also possible (though, note that this option is synchronous and will block current thread execution, etc.):
public void Register(PessoaViewModel pessoaViewModel)
{
var registerCommand = _mapper.Map<RegisterNewPessoaCommand>(pessoaViewModel);
var pessoaId = Bus.SendCommand(registerCommand).GetAwaiter().GetResult();
// use `pessoaId` as needed
}
For completeness, I'll add that it would also be possible to use Bus.SendCommand(registerCommand).Result;
but this is generally considered bad practice as it will obfuscate any exceptions inside of an aggregate exception, etc.
Also, here's a solid answer to a similar question about how the unwrapping occurs.
In C#, what is the difference between methods that return async Taskint vs. Taskint?
The way I like to think about it is this:
The keyword
async
doesn't modify the return type. The return type is what it would be ifasync
was missing:Task<int>
in your case.The keyword
async
tells the compiler to rewrite the implementation of the method to make it asynchronous. Behind the scenes, the compiler will convert the method into a state machine so it operates asynchronously. This is also the only wayawait
will work.
In other words, async
affects how a method is implemented, but is not part of the method's signature.
Taking your example, this is how the signatures appear in the IL:
.method public hidebysig
instance class [System.Private.CoreLib]System.Threading.Tasks.Task`1<int32> Action1 () cil managed
.method public hidebysig
instance class [System.Private.CoreLib]System.Threading.Tasks.Task`1<int32> Action2 () cil managed
As to when to use async
(for the method implementation), my quick rule of thumb is to use async when the method I am writing needs to call and wait for another method that returns a Task
. In other words, when I need to use await
in the implementation of a method.
Several other questions/answers try and address this better than I can, though:
- How and when to use ‘async’ and ‘await’
- What is the purpose of "return await" in C#?
- How should we use async await?
Operator '==' can not be applied to operands of type 'int' and 'Taskint'
Yo can't call other function in EF, at first get the result of the 'GetMaxNews' then use it. like below sample code:
public async Task<int> GetMaxNews()
{
return await _context.PNewses.MaxAsync(s => s.Id);
}
public async Task<List<PNews>> LastNews()
{
int ResultOfGetMaxNews = await GetMaxNews();
return await _context.PNewses.Where(s => s.Id == ResultOfGetMaxNews ).ToListAsync();
}
cannot apply operator * to operands int and Taskint
Your method does not return an int
but a Task
that has a result type of int
. And this task is or may be still running when your method returns.
So you'll have to wait for that task to complete. You have (at least) two options to do that:
If the calling method is an
async
method (or can be declared asasync
), you can use theawait
keyword:public async Task CallingMethod()
{
int result = await YourMethod();
// do what you want the result
}This will convert the
CallingMethod
into a state machine . The control flow will be returned to the caller while theTask
is running and execution will be resumed after theawait
(assigning the result toresult
) when theTask
completed.You can use the
Result
property of the returnedTask<int>
:public void CallingMethod()
{
int result = YourMethod().Result;
// do what you want the result
}This will block execution and wait until the
Task
has completed and then assign the resultingint
toresult
.
Related Topics
Return/Consume Dynamic Anonymous Type Across Assembly Boundaries
How to Make a Background Worker Thread Set to Single Thread Apartment
Camera.Main Is Null When Performing Raycast
String.Isnullorempty(String) VS. String.Isnullorwhitespace(String)
Are 2 Dimensional Lists Possible in C#
Wait Some Seconds Without Blocking UI Execution
Who Should Call Dispose on Idisposable Objects When Passed into Another Object
Entity Framework - Retrieve Id Before 'Savechanges' Inside a Transaction
How to Read Single Excel Cell Value
Insert into C# with SQLcommand
Using Prepared Statement in C# with MySQL
How Does Task<Int> Become an Int
Get a List of Distinct Values in List
How to Programmatically Generate an X509 Certificate Using Only C#