Xamarin Forms网页调用永不返回结果

问题描述 投票:0回答:1

我有此代码:

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);
    ....

如何创建此异步并在页面构造函数中运行它?

c# xamarin xamarin.forms xamarin.android xamarin.ios
1个回答
0
投票

混合异步等待并阻止呼叫,例如.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);
}

参考Async/Await - Best Practices in Asynchronous Programming

© www.soinside.com 2019 - 2024. All rights reserved.