我们已经使用Xamarin.Forms开发了现有的iOS应用程序。现在我们想扩展到Android和Windows Phone。在现有应用程序中,所有Web服务调用都是同步进行的。 Windows phone仅支持异步调用,因此我们考虑将异步调用包装为同步。
我们正在使用HttpClient.PostAsync方法来访问该服务。一旦执行命中PostAsync方法,手机就会挂起。调用服务的代码如下:
private static async void CallService(System.Uri uri)
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Host = uri.Host;
client.Timeout = System.TimeSpan.FromSeconds(30);
HttpContent content = new StringContent("", Encoding.UTF8, "application/xml");
var configuredClient = client.PostAsync(uri, content).ConfigureAwait(false);
var resp = configuredClient.GetAwaiter().GetResult();
resp.EnsureSuccessStatusCode();
responseString = resp.StatusCode.ToString();
resp.Dispose();
client.CancelPendingRequests();
client.Dispose();
}
}
我知道这是因为阻止了UI线程,所以只有我实现了ConfigureAwait(false),但这根本不起作用。我尝试使用System.Net.WebClient但结果相同。
现在,我将如何使这个异步调用在Windows Phone 8中同步处理?
答案 0 :(得分:5)
首先避免使用 async void 方法,因为您无法轻易等待其完成。返回Task
代替,在async
方法内,您不需要做一些特别的事情来返回Task
。编译器会为您完成所有工作。
您需要等待HttpClient.PostAsync
的调用,这应该足以让用户界面保持响应。
private static async Task CallService(System.Uri uri)
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Host = uri.Host;
client.Timeout = System.TimeSpan.FromSeconds(30);
HttpContent content = new StringContent("", Encoding.UTF8, "application/xml");
var resp = await client.PostAsync(uri, content);// Await it
resp.EnsureSuccessStatusCode();
responseString = resp.StatusCode.ToString();
resp.Dispose();
client.CancelPendingRequests();
}
}
注意:我已删除了ConfigureAwait(false)
,因为这不是必需的。如果你真的需要它,你可以加回来。