坚持异步方法

时间:2013-04-17 18:08:45

标签: c# multithreading async-await

可能有一些明显的错误,但我正在做一些没经验过的事情。我正试图从互联网上获取一个字符串,但它不起作用。在WinRT中,我们必须在异步方法中使用HttpClient,我做了如下: -

    private async void update()
    {
        try
        {   
                rawdata = await client.GetStringAsync(url);     

        }
        catch
        {
            rawdata = "Updation failed. Error code:vish42042";
        }

      }

现在,以下是代码的调用方式: -

    string temp = @url;
                update();
          WAIT:
                if (rawdata == null) {
                    goto WAIT;
                }

rawdata是一个全局变量,我做了这个检查goto WAIT:看看代码失败到底在哪里,它在这里失败了。当从数据库更新rawdata时,我期待if循环中断,但它永远不会发生。我是以错误的方式做的吗?(显然,我不是以我所知道的最佳方式做到这一点,但这也是错误的吗?)。问题在哪里?

更新:实际上问题不在于如何使这个功能工作,它正在进行一两个修改。真正的问题是如何确保在调用update()函数后更新rawdata,因为此后的代码期望它不会为null但是更新。

经过一些非常好的解释和答案之后,我认为这是问题可以解决的问题: -

     string xmlstring = xmlupobj.getUpdatedData(); 
     // Above is the ultimate point of return of data. 
    //Next code line is this, which throws a null exception 
                    XDocument xmldoc = XDocument.Parse(xmlstring);

所以我认为在使getUpdatedData()async之后,返回Task,如果我们可以将Task转换为正确的字符串以备已下载,如果尚未下载则返回null,那么我们可以使用一些不良的代码行来检查如: -

    string xmlstring = xmlupobj.getUpdatedData();
    WAIT:
        if (xmlstring == null)
        {
            goto WAIT;
        }
        xmldoc = XDocument.Parse(xmlstring);

所以,如果它是正确的,唯一的问题仍然是如何设置xmlstring?

2 个答案:

答案 0 :(得分:3)

您应该让此方法返回Task

private async Task update()
{
    try
    {
        using (var client = new HttpClient())
        {
            rawdata = await client.GetStringAsync(url);     
        }
    }
    catch
    {
        rawdata = "Updation failed. Error code:vish42042";
    }
}  

然后当你打电话时:

string temp = @url;
await update();

// rawdata will be set here

另一种选择是直接返回字符串,而不是在变量中设置它:

private async Task<string> UpdateAsync()
{
    try
    {
        using (var client = new HttpClient())
        {
            return await client.GetStringAsync(url);     
        }
    }
    catch
    {
        return "Updation failed. Error code:vish42042";
    }
}  

然后您可以通过以下方式获取数据:

string rawdata = await UpdateAsync();

请注意,这两种方法都要求调用者也是async方法。

答案 1 :(得分:2)

根据您的更新:

  

实际上问题不在于如何使这个功能工作,它正在进行一两个修改。真正的问题是如何确保在调用update()函数后更新rawdata,因为此后的代码期望它不会为null但是更新。

答案很简单。 你不能

使方法异步的整个目的是调用update不会将值设置为正确,它将启动一些工作单元,将其设置为在未来的某个未知点同时让您继续使用该程序而不是等待。为了确保在update返回之前设置变量,您需要使方法同步,并在方法内等待值存在,而不是使用异步。

如果你想保持update不同步,那么你需要进行一些简单的修改,如Reed's answer所示,以便在调用结果的时候通知调用者,并且那么您可以await方法,或者使用ContinueWith手动添加延续,以便在计算结果后执行所需的代码。