2016-11-28 237 views
-3

我目前正在開發一些項目。我需要將一個項目添加到數據庫,然後執行另一個請求以獲取剛添加的項目。當然,一切都必須是非阻塞的,用戶需要能夠在後臺執行這些操作的同時仍然可以使用該應用程序。等待異步函數結束後再執行另一個

這裏是我使用的代碼:

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

我想等待AddItem要執行調用GetItem(id)之前,因爲我需要的項目在數據庫中得到它之前加入。但是,似乎並非如此。

我試圖把調試信息的GetItemAddItem功能,在郵件內的GetItem顯示開頭的消息之前在AddItem結束。

如何確保在不阻止用戶的情況下等待AddItem的結束?

編輯

的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)); 
} 

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); 
} 
+1

@mybirthname使調用異步並不一定使它們併發。事實上,在上面的例子中,它們已經是連續的。 –

+3

該代碼應該已經做你所描述的,你能解釋你爲什麼要問嗎?在AddItem完成之前,'await AddItem'不應該繼續執行當前的方法。您可能需要在'AddItem'內部發布代碼。 –

+1

在你提供的例子中,'AddItem'將在'GetItem'被調用之前完成。如果這不是你所看到的行爲,你需要分享更多的代碼。 –

回答

0

答案就在你的AddItem方法。 你應該等待post方法。當你不指日可待,它仍然執行,但您的代碼不等待它完成,並一直走,由於這種行爲的GetItem的作品比的AddItem

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

更快,但我想這更好的辦法執行此

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

你需要等待從後這樣的結果:

await _client.Post<string>("/item", param); 

否則將繼續執行到它只是將返回該項目下一線p然後返回到await AddItem(new Item(...params here ...);,此時該呼叫已被滿足並完成。因此,執行將轉到下一行是:

return new ItemAdded(await GetItem(id)); 

但顯然未必已添加的項目,因爲你所謂的後,回到馬上,而無需等待它完成。可能是這裏的關鍵字。在某些情況下,當您調用ItemAdded時,它可能已被添加。