从Xamarin PCL调用REST API时程序挂起

时间:2016-04-18 09:38:34

标签: c# json xamarin xamarin.android portable-class-library

我的Xamarin PCL中有以下代码

    public Product Product(int id)
    {

        var product = Get<Product>(endpoint + "?id=" + id).Result;
        return product;
    }

    static async Task<T> Get<T>(string endpoint)
    {
        using (var client = new HttpClient())
        {
            var response = await client.GetAsync(endpoint);
            string content = await response.Content.ReadAsStringAsync();
            return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
        }
    }

我的程序只是挂在这一行

var response = await client.GetAsync(endpoint);

没有例外。

我在控制台应用程序中执行相同的代码,它运行正常。

我能看到的唯一区别是,在我的控制台应用中,我引用了Newtonsoft.Json.dll文件夹中的lib\net45。在我的Xamarin PCL项目中,我引用了Newtonsoft.Json.dll文件夹中的lib\portable-net40+sl5+wp80+win8+wpa81。我尝试在lib\portable-net45+wp80+win8+wpa81+dnxcore50文件夹中引用dll,结果相同。

我正在使用Json 8.0.3

2 个答案:

答案 0 :(得分:2)

代码挂起,因为您正在访问任务的Result属性。您应该使用await关键字从任务中获取结果。

发生死锁是因为同步上下文是由两个不同的线程捕获的。有关详细信息,请参阅此答案:await vs Task.Wait - Deadlock?

它适用于控制台应用程序,因为SynchronizationContext.Current为空,因此不会发生死锁。有关详情,请参阅此帖子:Await, SynchronizationContext, and Console Apps

答案 1 :(得分:2)

您正在通过访问Result属性

强制异步操作​​在同步方法中运行
public async Task<Product> Product(int id)
{

    var product = await Get<Product>(endpoint + "?id=" + id);
    return product;
}

如上修改产品方法将修复它。