我正在尝试通过HttpClient进行异步调用以从RESTful WCF服务加载数据。该代码位于Xamarin UI中使用的可移植类库(PCL)中。似乎异步调用永远不会被触发。我已经阅读了关于这方面问题的博客,我相信我已经解决了这些问题。
我从客户端数据存储库类进行调用,如下所示:
public MyRepository()
{
Task.Run(async () => { await LoadDataAsync(url); });
}
public async Task LoadDataAsync(string uri)
{
if (allRecords != null) **// Breakpoint here never hit.**
{
string responseJsonString = null;
using (var httpClient = new HttpClient())
{
try
{
Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri);
HttpResponseMessage response = await getResponse;
responseJsonString = await response.Content.ReadAsStringAsync();
myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString);
}
catch (Exception ex)
{
}
}
}
}
任何帮助非常感谢。提前谢谢。
答案 0 :(得分:2)
如果我是你,我会避免在构造函数中调用异步方法..
并做这样的事情
(创建一个返回类实例的静态方法)
const string uri = "https://www.webservice.com/api/getdata";
private List<MyListItem> myList;
public static async Task<MyRepository> GetMyRepository()
{
MyRepository myRepository = new MyRepository();
await myRepository.LoadDataAsync(uri);
return myRepository;
}
public MyRepository()
{
}
public async Task LoadDataAsync(string uri)
{
if (allRecords != null) **// Breakpoint here never hit.**
{
string responseJsonString = null;
using (var httpClient = new HttpClient())
{
try
{
Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri);
HttpResponseMessage response = await getResponse;
responseJsonString = await response.Content.ReadAsStringAsync();
myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString);
}
catch (Exception ex)
{
}
}
}
}
我无法解释您遇到此问题的原因,但这可能会对您有所帮助。
答案 1 :(得分:0)
问题是你在构造函数中调用了“即发即忘”的异步调用。这应该是可以避免的,并且是你的代码没有被调用的原因 - 当它可能是......我建议做出以下改变:
public async Task LoadDataAsync(string uri)
{
if (allRecords != null) **// Breakpoint here never hit.**
{
string responseJsonString = null;
using (var httpClient = new HttpClient())
{
try
{
Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri);
HttpResponseMessage response = await getResponse;
responseJsonString = await response.Content.ReadAsStringAsync();
myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString);
}
catch (Exception ex)
{
}
}
}
}
注意除了一起删除构造函数之外,实际上没有任何更改。实例化此对象时 - 只需等待LoadDataAsync
函数的调用。
public async Task SomeConsumerOfYourObject()
{
var wcfObj = new YourWcfObject();
await wcfObj.LoadDataAsync(this.Uri);
// Then you're good...
}
答案 2 :(得分:-2)
为什么它没有触发:可能是因为您的应用程序在您打算通过Task.Run启动的线程实际可以启动之前退出。
为了测试上述理论,请在调用后立即调用Thread.Sleep(这不是解决方案,而是测试):
public MyRepository()
{
Task.Run(async () => { await LoadDataAsync(url); });
System.Threading.Thread.Sleep(10000); //will sleep for 10 seconds
}
无论如何,为了利用异步方法你应该完全删除Task.Run,直接调用函数await,线程将在await运行&#34; getresponse&#34;之后产生。允许做其他事情的对象,直到你真的需要等待它,当你真的需要等待它时,然后打电话等待。