我正在寻找一些关于掌握 WPF 中的 Task
的建议,并且想知道是否有人可以查看我的代码并指出我做错了什么?
基本上,应用程序从 UI 获取邮政编码,用于实例化 Task
服务,该服务将获取经度/纬度,可通过实例访问,以用于其他服务或 UI 本身。
我想我可能有一个竞争条件,我希望在 ResultTextBlock.Text
设置为零时纠正它,但是通过实例化我看到了这些值设置。
如有任何关于Task
实现和布线的建议,我们将不胜感激。
服务代码
class PostcodeService
{
string _result;
string _postcode;
HttpResponseMessage _response;
RootObject rootObject;
public double Latitude { get; private set; }
public double Longitude { get; private set; }
public PostcodeService(string postcode)
{
this._postcode = postcode;
rootObject = new RootObject();
}
public async Task<string> GetLongLatAsync()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.postcodes.io/postcodes/" + this._postcode);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
_response = await client.GetAsync(client.BaseAddress);
if(_response.IsSuccessStatusCode)
{
//cast result into model and then set long/lat properties which can then be used in the UI
_result = await _response.Content.ReadAsStringAsync();
rootObject = JsonConvert.DeserializeObject<RootObject>(_result);
Longitude = Double.Parse(rootObject.result.longitude.ToString());
Latitude = Double.Parse(rootObject.result.latitude.ToString());
}
}
catch(Exception ex)
{
ex.ToString();
}
}
TaskCompletionSource<string> tc = new TaskCompletionSource<string>(_result);
return tc.ToString();
}
}
界面代码
private void PostcodeButton_Click(object sender, RoutedEventArgs e)
{
_clearStatus();
if (_validatePostcode())
{
Task T1 = Task.Factory.StartNew(async () =>
{
// get long lat from api
_postcode = new PostcodeService(PostcodeTextBox.Text);
await _postcode.GetLongLatAsync();
});
//Race condition?
ResultTextBlock.Text = _postcode.Latitude.ToString();
}
}
最佳答案
您的GetLongLatAsync()
方法应该返回一个字符串
:
public async Task<string> GetLongLatAsync()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.postcodes.io/postcodes/" + this._postcode);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
_response = await client.GetAsync(client.BaseAddress);
string result = null;
if (_response.IsSuccessStatusCode)
{
//cast result into model and then set long/lat properties which can then be used in the UI
result = await _response.Content.ReadAsStringAsync();
rootObject = JsonConvert.DeserializeObject<RootObject>(_result);
Longitude = Double.Parse(rootObject.result.longitude.ToString());
Latitude = Double.Parse(rootObject.result.latitude.ToString());
}
return result;
}
}
...您只需在 UI 中等待 GetLongLatAsync()
:
private async void PostcodeButton_Click(object sender, RoutedEventArgs e)
{
_clearStatus();
if (_validatePostcode())
{
// get long lat from api
_postcode = new PostcodeService(PostcodeTextBox.Text);
string result = await _postcode.GetLongLatAsync();
ResultTextBlock.Text = result.ToString();
}
}
您不需要使用 TaskCompletionSource
也不需要启动新的 Task
来调用异步方法。
关于c# - 在 WPF 应用程序中正确实现任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55261660/