我早些时候问过,但没有一个回复结束了。 所以我有一个类来创建一个Web请求来获取一串数据,并在该类中调用方法来执行该操作,然后返回字符串值。
我有MainPage类,City Class(WebRequest返回一个JSON字符串,这个类解析它并存储数据),我有一个WebRetrieval类。
在MainPage中我有这个:
private void City_GoButton_Click(object sender, RoutedEventArgs e)
{
City cityObject = new City();
WebRetrieval wr = new WebRetrieval();
string jsonString;
string formattedString;
if (String.IsNullOrWhiteSpace(CityID_Textbox.Text))
{
MessageDialog md = new MessageDialog("Please enter in a number");
md.ShowAsync();
}
else
{
long cityNum = Convert.ToInt64(CityID_Textbox.Text);
string url = "http://honey.computing.dcu.ie/city/city.php?id=" + cityNum;
jsonString = wr.GetResult(url);
formattedString = cityObject.ReturnFormattedString(jsonString);
}
}
在Web Retrieval类中,我有这个:
async public void GetInformation(string url)
{
var client = new HttpClient();
var response = await client.GetAsync(new Uri(url));
result = await response.Content.ReadAsStringAsync();
}
public string GetResult(string url)
{
GetInformation(url);
return result;
}
奇怪的是,在WebRetrieval类中,在GetInformation方法内部,当它尝试执行响应时,程序跳转到我的City类并失败,因为它收到的字符串为null。它永远不会进入GetInformation方法内的结果行。
我觉得这与GetInformation异步并且响应等待它的事实有关,但我不知道如何解决它,因为另一个问题中的建议没有结束工作
希望有人可以帮我解决这个问题。 干杯
答案 0 :(得分:2)
你应该避免async void
。我在MSDN文章Best Practices in Asynchronous Programming中解释了“为什么”的全部细节。
void
方法, async
是一种非常不自然的返回类型。您只应在编写async
事件处理程序时使用它(必须返回void
)。
因此,将所有async void
方法转换为async Task
(以及following the naming convention):
async public Task GetInformationAsync(string url)
{
var client = new HttpClient();
var response = await client.GetAsync(new Uri(url));
result = await response.Content.ReadAsStringAsync();
}
这些任务必须是await
ed:
public string GetResult(string url)
{
await GetInformationAsync(url);
return result;
}
然后编译器会抱怨如果你使用await
,你必须使用你的方法async
,所以我们这样做:
public async Task<string> GetResultAsync(string url)
{
await GetInformationAsync(url);
return result;
}
await
也是:
private void City_GoButton_Click(object sender, RoutedEventArgs e)
{
...
jsonString = await wr.GetResultAsync(url);
formattedString = cityObject.ReturnFormattedString(jsonString);
}
再一次,编译器抱怨,所以我们通过调用方法async
来解决这个问题(通常我们会将其设为async Task
,但它必须是async void
,因为它是事件处理程序):
private async void City_GoButton_Click(object sender, RoutedEventArgs e)
{
...
jsonString = await wr.GetResultAsync(url);
formattedString = cityObject.ReturnFormattedString(jsonString);
}
你已经完成了。
您可能会发现我的async
intro有帮助。
答案 1 :(得分:1)
如果我理解正确,GetResult
正在调用GetInformation
,这是async
方法。基本上,GetResult
的内部不需要等待GetInformation
调用完成才能完成。你有时间问题。
一些可能的解决方案可能是将GetResult
标记为async
,让它等待GetInformation
,或让GetInformation
返回一个值,然后您可以通过在任务上调用.Result
来强制完成。