簡體   English   中英

C#異步不等待

[英]C# async doesn't await

我正在使用的應用程序應該使用http客戶端檢索json字符串,然后反序列化並在應用程序中使用。

一切正常,除了等待功能。 我做錯了事,似乎無法弄清楚。 我怎樣才能確保我的DataService類一直等到我有json並反序列化之后?

DataService類:

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 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 {}
    }
}

經過大量的試驗和錯誤,我意識到對於這個特別的事情,它不必是異步的,所以我剛剛在主線程上重新創建,並取得了成功:

DataService類:

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

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

我的http客戶端類:

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構造函數中不await就調用Retrieve() ,這就是為什么不等待您的方法的原因。

您最好使用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();

當然,這兩行代碼也必須從異步方法中調用。 (異步/一直等待)

經過大量的試驗和錯誤,我意識到對於這個特別的事情,它不必是異步的,所以我剛剛在主線程上重新創建,並取得了成功:

DataService類:

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

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

我的http客戶端類:

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 {}
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM