How Does Task<Int> Become an Int

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 type T 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 if async 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 way await 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:

  1. If the calling method is an async method (or can be declared as async), you can use the await 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 the Task is running and execution will be resumed after the await (assigning the result to result) when the Task completed.

  2. You can use the Result property of the returned Task<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 resulting int to result.



Related Topics



Leave a reply



Submit