2013-04-17 27 views
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是一個全球性的varible,我做了這個檢查轉到WAIT:看看代碼失敗的地方,以及它在這裏失敗。我期待着當rawdata從互聯網更新時,if循環會中斷,但它永遠不會發生。我做錯了什麼?(顯然我不是以我所知道的最好的方式去做,但它也錯了嗎?)。哪裏有問題?

更新:其實問題不是如何使這個功能工作,它正在進行修改或兩個。真正的問題是如何確保一旦update()函數被調用後更新rawdata,因爲此後的代碼期望它不爲空,而是更新。

一些很好的解釋和答覆後,我想,那麼這就是問題是可以解決的問題: -

 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()異步,返回任務,如果我們可以轉換後任務以適當的字符串的情況下,它已被下載和null如果尚未下載的話,我們可以檢查使用的代碼一些不好的線路爲: -

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

所以,如果它是正確的,唯一的遺骸問題是如何設置xmlstring的?

+0

@torrentialcoding我不知道爲什麼你的編輯建議被拒絕,這顯然是有效的。我希望你不要介意我用我的名字推動你的編輯。 – hvd

+0

@ hvd沒問題,無論是誰編輯,恢復它都是正確的做法。 :) –

+1

即使你*可以*做你想做的事(*等待update()完成)你的應用程序將阻止主線程和認證失敗。 –

回答

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方法,以及。

+2

更好的是,改變它返回一個'任務'而不是修改一個全局變量。 – Servy

+0

我試過了。但是然後它給出了一個錯誤,await關鍵字只能用在async方法中,所以我必須使這種方法異步嗎? – vish213

+2

@ vish213是的 - 你會需要這是一個異步方法 –

2

根據您的更新:

其實問題不在於如何使該功能的工作,它正在與一個或兩個修改。真正的問題是如何確保一旦update()函數被調用後更新rawdata,因爲此後的代碼期望它不爲空,而是更新。

答案很簡單。 你不能

製作方法異步的整個目的是呼籲update將不設置值權那麼那裏,它就會開始工作的一些單位,將其設置在一些未知的點在未來同時讓你繼續而不是等待。爲了確保變量在update返回之前設置,您需要使方法同步,並在方法內部等待值存在,而不是使用異步。

如果你想保持update臺異步,那麼你就需要做一些簡單的修改,如Reed's answer指示允許呼叫者被通知當結果已經計算的,然後您可以await方法,或者手動添加使用ContinueWith的延續,一旦計算出結果就執行所需的代碼。

+0

謝謝你的明確答案。其實我開發了一個WPF應用程序,現在我只是將它轉換成WinRT應用程序。我在WPF中的方法顯然是同步的,但由於WinRT中的限制,我們無法在同步方法中使用WebClient,所以我試圖找到最佳選擇。 – vish213

+0

@ vish213最好的選擇是讓你的代碼「一路上漲」,就像其他人已經提到過的那樣。 – svick