C#Web请求导致崩溃

时间:2013-11-12 17:53:48

标签: c# windows web request response

我早些时候问过,但没有一个回复结束了。 所以我有一个类来创建一个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异步并且响应等待它的事实有关,但我不知道如何解决它,因为另一个问题中的建议没有结束工作

希望有人可以帮我解决这个问题。 干杯

2 个答案:

答案 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来强制完成。