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 {}
}
}
我正在开发的应用程序应该使用 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 {}
}
}