Pictar Pictar - 5 days ago 5
C# Question

Wait for an async function to end before executing another

I'm currently working on some project. I need to add an item to a database and after doing that, executing another request to get the item I just added. Of course, everything must be non-blocking and the user needs to be able to still use the application while these operations execute in background.

Here is the code I use :

await AddItem(new Item(...params here ...);
return new ItemAdded(await GetItem(id));


I'd like to wait for
AddItem
to be executed before calling
GetItem(id)
, cause I need the item to be added in the database before getting it. However, it seems than this is not the case.

I tried to put debug message inside of the
GetItem
and
AddItem
functions and the message at the beginning of
GetItem
displays before the message at the end of
AddItem
.

How can I make sure to wait the end of
AddItem
while not blocking the user ?

EDIT

AddItem

public Task<Item> AddItem(Item item) {
return Task.Run(() => {
var param = ... params ...
_client.Post<string>("/item", param);
return item;
});
}


GetItem

public Task<Item> GetItem(Guid id)
{
return Task.Run(() => _client.Get<Item>("/item/" + id));
}


Post

public async Task<T> Post<T>(string path, Dictionary<string, string> parameters)
{
var response = await _httpClient.PostAsync(_apiUrl + path, new FormUrlEncodedContent(parameters));
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(result);
}

Answer

The answer is in your AddItem method. You should await for the post method. When you don't await for it, it still performs, but your code doesn't wait for it finishing and keeps going, due to this behaviour GetItem works faster than AddItem

public Task<Item> AddItem(Item item) { 
return Task.Run(async () => { 
    var param = ... params ... 
    await _client.Post<string>("/item", param); 
    return item; 
}); 

But I suppose that the better way to perform this

public async Task<Item> AddItem(Item item) { 
    var param = ... params ... 
    await _client.Post<string>("/item", param); 
    return item; 
}
Comments