Reputation: 45
private async Task<string> GetStateInfo()
{
var cityId = await GetCityIdByNameAsync("Delhi");
var state = await GetStateNameAsync(cityId);
return state;
}
As we know async and await are used for asynchronous programing and they are for non-blocking programming model. But in the code above the var state = await GetStateNameAsync(cityId); executes when the 1st line executes as it takes input from that. So I dont understand is it a blocking call or non-blocking call?
Upvotes: 4
Views: 1797
Reputation: 594
There are 2 basic topics/questions that should be covered. I think we always miss discussing the second topic of using await
.
await
keyword to make the thread awaited?Let me discuss these 2 topics with an example. Technical details will be kept aside for now.
Let's say we have one method CreateSale
public void CreateSale(int saleId, int customerId)
{
var transactionId = AddTransactionToPaymentGateway(saleId, customerId);
SaveSaleToLedger(transactionId, customerId);
}
Now, assume that at the same moment, there are 2 users that initiate the CreateSale
operation. In a synchronous way, the thread starts to execute the operations like the below,
1. User:1 → AddTransactionToPaymentGateway
-- Wait until the job is done. --
2. User:1 → SaveSaleToLedger
-- Wait until the job is done. --
3. User:2 → AddTransactionToPaymentGateway
-- Wait until the job is done. --
4. User:2 → SaveSaleToLedger
-- Wait until the job is done. --
In the synchronous method, the thread will wait for each operation to be done before starting the next one. Also, notice that in this waiting period, the thread remains fully idle. The operations are DB intensive (let's say) and the thread just waits and does nothing. This will make the user2 wait unnecessarily to start his operation whereas the thread remains idle.
In asynchronous programming, we do not block the thread idly. Rather it should start executing the next operations.
public async Task CreateSaleAsync(int saleId, int customerId)
{
var transactionId = AddTransactionToPaymentGatewayAsync(saleId, customerId);
SaveSaleToLedgerAsync(transactionId, customerId);
}
1. User:1 → AddTransactionToPaymentGatewayAsync
2. User:1 → SaveSaleToLedgerAsync
3. User:2 → AddTransactionToPaymentGatewayAsync
4. User:2 → SaveSaleToLedgerAsync
Now the thread is not waiting for any of the jobs done.
And here is the answer to the first topic.
await
?In the async version of the code, the thread is not waiting for any of the jobs to be done. But this approach will create another issue.
Look, as it is not waiting for the first job of the User1
but rather starting the second job of the same user, this will break the application. Because we do not get any transactionId
yet to start the second job.
To overcome the issue, here comes the savior await
.
With await
we are telling the thread that okay, you are good to do your tasks asynchronously but not mine!! You should wait for my tasks to be done to execute the next. But in the meantime, you are free to serve other users.
public async Task CreateSaleAsync(int saleId, int customerId)
{
var transactionId = await AddTransactionToPaymentGatewayAsync(saleId, customerId);
await SaveSaleToLedgerAsync(transactionId, customerId);
}
1. User:1 → AddTransactionToPaymentGatewayAsync
2. User:2 → AddTransactionToPaymentGatewayAsync
3. User:1 → SaveSaleToLedgerAsync //start after task 1 is done
4. User:2 → SaveSaleToLedgerAsync //start after task 2 is done
Look how the thread is starting the User2
's tasks before User1
's SaveSaleToLedgerAsync task.
It also remembers that the User1
has a job running. And whenever the job is done it will start the 2nd task of the user. But in the meantime, it will serve other users' tasks.
This is the job of the keyword await
. Again, the await
does not block other user's tasks. It is still asynchronous. It just waits for the current user's task.
Hope this explains well.
Upvotes: 4
Reputation: 456507
Please see my async intro. await
is an "asynchronous wait", so it "pauses" the method and returns an incomplete Task<string>
instance. So the method is waiting for the task returned by GetCityIdByNameAsync
to complete, but there is no thread blocked waiting for it.
Upvotes: 6