异步调用永远不会被解雇

时间:2016-04-22 02:51:50

标签: c# async-await dotnet-httpclient

我正在尝试通过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)
                {

                }
            }
        }
    }

任何帮助非常感谢。提前谢谢。

3 个答案:

答案 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;之后产生。允许做其他事情的对象,直到你真的需要等待它,当你真的需要等待它时,然后打电话等待。