我有此代码:
public async Task<List<Template>> GetTemplates(User user)
{
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("un", user.Username));
postData.Add(new KeyValuePair<string, string>("pw", user.Password));
var content = new FormUrlEncodedContent(postData);
var weburl = "myapp.org/get_templates.php";
var response = await PostResponseTemplates<Template>(weburl, content);
return response;
}
public async Task<List<Template>> PostResponseTemplates<List>(string weburl, FormUrlEncodedContent content)
{
var response = await client.PostAsync(weburl, content);
var json = response.Content.ReadAsStringAsync().Result;
.......
}
但是网络电话在此行之后永远不会返回结果:var response = await client.PostAsync(weburl, content);
。
我在做什么错?
这里是我现在调用该函数的空白处:
public MemeTemplateList()
{
InitializeComponent();
LoadTemplateList();
}
private void LoadTemplateList()
{
var templateList = App.RestService.GetTemplates(App.User);
....
如何创建此异步并在页面构造函数中运行它?
混合异步等待并阻止呼叫,例如.Result
public async Task<List<Template>> PostResponseTemplates<List>(string weburl, FormUrlEncodedContent content) {
var response = await client.PostAsync(weburl, content);
var json = response.Content.ReadAsStringAsync().Result; //<--THIS WILL DEADLOCK
//...omitted for brevity
可能导致死锁。这就是为什么函数不返回的原因。
删除.Result
,并使代码一直保持异步状态
public async Task<List<Template>> PostResponseTemplates<List>(string weburl, FormUrlEncodedContent content) {
var response = await client.PostAsync(weburl, content);
var json = await response.Content.ReadAsStringAsync(); //<--THIS
//...omitted for brevity
我也建议将功能定义从通用定义更改为其他>
public async Task<List<Template>> PostResponseTemplates(string weburl, FormUrlEncodedContent content) { //... }
由于函数中已经知道类型
List<Template> response = await PostResponseTemplates(weburl, content);
最后确保所有内容在整个调用堆栈中都是异步的
public MemeTemplateList() {
InitializeComponent();
//Subscribe to event
loadingTemplates += onLoadingTemplates;
//raise the event to load the templates.
LoadTemplateList();
}
private event EventHandler loadingTemplates = delegate { };
//ASYNC VOID ONLY ALLOWED ON EVENT HANDLER!!!!!!!
private async void onLoadingTemplates(object sender, EventArgs args) {
List<Template> templateList = await App.RestService.GetTemplates(App.User);
//....
}
private void LoadTemplateList() {
loadingTemplates(this, EventArgs.Empty);
}