1

可能有一些明显的错误,但我正在做一些没有经验的事情。我正在尝试从互联网上获取一个字符串,但它不起作用。在 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() 异步后,返回 Task,如果我们可以将 Task 转换为正确的字符串以防它已下载,如果尚未下载则为 null,那么我们可以使用一些错误的代码行进行检查:-

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

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

4

2 回答 2

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方法。

于 2013-04-17T18:11:31.303 回答
2

Based on your update:

Actually the problem is not HOW TO MAKE THIS FUNCTION WORK, it is working with a modification or two. The real problem is how do I make sure that rawdata is updated once update() function is called, because the code thereafter is expecting it not to be null but updated.

The answer is simple. You can't.

The entire purpose of making the method asynchronous is that calling update will not set the value right then an there, it will start some unit of work that will set it at some unknown point in the future while letting you continue on with the program instead of waiting. In order to ensure that the variable is set before update returns you need to make the method synchronous, and wait inside of the method for a value to exist, instead of using asynchrony.

If you would like to keep update asychronous then you'll need to make some simple modifications, as indicated in Reed's answer to allow the caller to be notified of when the result has been computed, and then you can either await the method, or manually add a continuation using ContinueWith, to execute the desired code once the result has been computed.

于 2013-04-17T18:50:51.307 回答