从 Xamarin PCL 调用 REST API 时程序挂起
Program hangs when calling REST API from Xamarin PCL
我的 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);
没有抛出异常。
我在控制台应用程序中执行相同的代码,它工作正常。
我能看到的唯一区别是,在我的控制台应用程序中,我在 lib\net45
文件夹中引用了 Newtonsoft.Json.dll
。在我的 Xamarin PCL 项目中,我在 lib\portable-net40+sl5+wp80+win8+wpa81
文件夹中引用 Newtonsoft.Json.dll
。我尝试引用 lib\portable-net45+wp80+win8+wpa81+dnxcore50
文件夹中的 dll,结果相同。
我正在使用 Json 8.0.3
代码挂起,因为您正在访问任务的 Result
属性。您应该改为使用 await
关键字从任务中获取结果。
死锁的发生是因为同步上下文被两个不同的线程捕获。有关详细信息,请参阅此答案:await vs Task.Wait - Deadlock?
它在控制台应用程序中工作,因为 SynchronizationContext.Current
为空,因此不会发生死锁。有关详细信息,请参阅此 post:Await, SynchronizationContext, and Console Apps
您正在通过访问结果 属性
在同步方法中强制异步操作 运行
public async Task<Product> Product(int id)
{
var product = await Get<Product>(endpoint + "?id=" + id);
return product;
}
如上修改 Product Method 即可解决。
我的 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);
没有抛出异常。
我在控制台应用程序中执行相同的代码,它工作正常。
我能看到的唯一区别是,在我的控制台应用程序中,我在 lib\net45
文件夹中引用了 Newtonsoft.Json.dll
。在我的 Xamarin PCL 项目中,我在 lib\portable-net40+sl5+wp80+win8+wpa81
文件夹中引用 Newtonsoft.Json.dll
。我尝试引用 lib\portable-net45+wp80+win8+wpa81+dnxcore50
文件夹中的 dll,结果相同。
我正在使用 Json 8.0.3
代码挂起,因为您正在访问任务的 Result
属性。您应该改为使用 await
关键字从任务中获取结果。
死锁的发生是因为同步上下文被两个不同的线程捕获。有关详细信息,请参阅此答案:await vs Task.Wait - Deadlock?
它在控制台应用程序中工作,因为 SynchronizationContext.Current
为空,因此不会发生死锁。有关详细信息,请参阅此 post:Await, SynchronizationContext, and Console Apps
您正在通过访问结果 属性
在同步方法中强制异步操作 运行public async Task<Product> Product(int id)
{
var product = await Get<Product>(endpoint + "?id=" + id);
return product;
}
如上修改 Product Method 即可解决。