C# 异步不等待

C# async doesn't await

我正在开发的应用程序应该使用 http 客户端检索 json 字符串,然后反序列化并在应用程序中使用。

一切正常,除了等待功能。我做错了什么,我似乎无法弄清楚是什么。我怎样才能确保我的数据服务 class 一直等到我有我的 json 并且它已被反序列化?

数据服务class:

class DataService : IDataService
{
    private IEnumerable<Concert> _concerts;

    public DataService()
    {
        _concerts = new DataFromAPI()._concerts;

        Debug.WriteLine("____Deserialization should be done before continuing____");

        **other tasks that need the json**

    }
}

我的 http 客户端 class:

class DataFromAPI
{

    public IEnumerable<Concert> _concerts { get; set; }

    public DataFromAPI()
    {
        Retrieve();
    }

    public async Task Retrieve()
    {
        try
        {
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage();
            var result = await client.GetAsync(new Uri("http://url-of-my-api"), HttpCompletionOption.ResponseContentRead);
            string jsonstring = await result.Content.ReadAsStringAsync();
            DownloadCompleted(jsonstring);
        }
        catch {}

    }

    void DownloadCompleted(string response)
    {
        try
        {
            _concerts = JsonConvert.DeserializeObject<IEnumerable<Concert>>(response.ToString());

        }
        catch {}
    }
}

解决方案

经过多次试验和错误后,我意识到对于这个特殊的东西它不必是异步的,所以我只是在主线程上重新创建,并成功:

数据服务class:

class DataService : IDataService
{
    private IEnumerable<Concert> _concerts;

    public DataService()
    {
        _concerts = new DataFromAPI()._concerts;
    }
}

我的 http 客户端 class:

public static class DataFromAPI
{ 
    public void Retrieve()
    {
        try
        {
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage();
            var result = client.GetAsync("http://url-of-my-api").Result;
            if (result.IsSuccessStatusCode)
            {
                var responseContent = result.Content;   
            }
            DownloadCompleted(result.Content.ReadAsStringAsync().Result);
        }
        catch {}
    }
}

您在 DataFromAPI 构造函数中调用 Retrieve() 而没有 await,这就是为什么不等待您的方法的原因。

您最好在构造函数之外调用此方法,使用 await 关键字,如下所示:

await Retrieve();

你必须稍微重构一下你的代码。这是一个例子:

public class DataService : IDataService
{
    private IEnumerable<Concert> _concerts;

    public async Task LoadData()
    { 
        _concerts = await DataFromAPI.Retrieve();
        **other tasks that need the json**
    }
}

public static class DataFromAPI
{ 
    public static async Task<IEnumerable<Concert>> Retrieve()
    {
        try
        {
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage();
            var result = await client.GetAsync(new Uri("http://url-of-my-api"), HttpCompletionOption.ResponseContentRead);
            string jsonstring = await result.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<IEnumerable<Concert>>(response.ToString());
        }
        catch(Exception)
        {
        }
        return Enumerable.Empty<Concert>();
    }
}

然后,当您创建 DataService 实例时,就在您必须调用它的 LoadData() 方法之后。

DataService ds = new DataService();
await ds.LoadData();

当然,这两行代码也必须从异步方法中调用。 (异步/一直等待)

经过多次试验和错误后,我意识到对于这个特殊的东西它不必是异步的,所以我只是在主线程上重新创建,并成功:

数据服务class:

class DataService : IDataService
{
    private IEnumerable<Concert> _concerts;

    public DataService()
    {
        _concerts = new DataFromAPI()._concerts;
    }
}

我的 http 客户端 class:

public static class DataFromAPI
{ 
    public void Retrieve()
    {
        try
        {
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage();
            var result = client.GetAsync("http://url-of-my-api").Result;
            if (result.IsSuccessStatusCode)
            {
                var responseContent = result.Content;   
            }
            DownloadCompleted(result.Content.ReadAsStringAsync().Result);
        }
        catch {}
    }
}