2014-03-30 50 views
0

這是我認爲我確切知道發生了什麼,但一直無法確定如何在Windows Phone 8上修復它的這些事情之一。我希望有兩種方法可以讀取通過http;一個同步和一個異步。同步功能目前正在從UI線程調用,但最終可能不會。 相關的代碼如下所示:在UI線程上同步使用DownloadStringTaskAsync

private static string result; 

public static string load() { 
    Task task = loadAsync(); 
    task.Wait; 
    return result; 
} 

public async static Task <string> loadAsync() { 
     ... 
    result = await webClient.DownloadStringTaskAsync(uri); 
} 

我打算當我打電話Task.Wait()UI線程會等到讀操作完成;沒關係 - 我希望UI暫停,直到讀取完成。但正如我寫的,我似乎正在創造一個僵局,以至於一切都停滯不前,並且下載從未完成,並且可能永遠不會開始。這是有道理的task.wait()是造成僵局,所以我創建了以下測試類:

public static class Test 
{ 
    const string apiUrl = @"http://169.254.21.12:51428/api/Q"; 
    private static WebClient webClient; 
    private static Uri uri; 
    private static string result; 

    public static string Load() 
    { 
     webClient = new WebClient(); 
     webClient.Headers["Accept"] = "application/json"; 
     uri = new Uri(apiUrl); 
     try 
     { 
      Task<string> task = webClient.DownloadStringTaskAsync(uri); 
      result = task.Result; 
     } 
     catch (Exception e) { result = null; } 
     return result; 
    } 

這個類是從VS13的WP8模擬器上運行,談論到本地IIS,還推出瞭如在同一個解決方案中單獨的項目。我們到達'結果='行,但該行永遠不會返回。我知道IIS正在運行,並且網絡鏈接正在工作,因爲我可以使用手機中的IE訪問URI。

+0

你是否試圖阻止UI線程?這是一個非常糟糕的主意。它沒有幫助,你已經顯示的代碼,甚至不會編譯... –

+0

嗨,喬恩,我很抱歉 - 我寫這個問題的方式不清楚。我已編輯希望解決。我可以發佈剩餘的代碼,但這只是WebClient的設置,所以似乎沒有任何意義。但如果有幫助,會做。 – jbhelicon

回答

1

你看到一個deadlock issue that I describe in detail on my blog

我想通過http讀取兩種方法;一個同步和一個異步。

這就是你的問題。下載HTTP資源是一種自然的異步操作,所以它只應該有一個異步API。

+0

博客文章是dispositive;謝謝。 「一路下跌」的建議是一個新口頭禪。 – jbhelicon

1

是的,你目前正在創建一個死鎖。

您使用異步/等待,這意味着,當任務被完成DownloadStringTaskAsync返回,繼續將計劃繼續從那裏離開,並回到UI線程loadAsync

但是,由於UI線程正在忙於等待任務完成...而且該任務僅在連續運行後纔會完成,所以該延續永遠不會實際運行。僵局。

只是爲了阻止UI線程,你不需要使用async/await可言:

// Method name changed to follow .NET conventions. 
public static string Load() { 
    WebClient webClient = ...; 
    Task<string> task = webClient.DownloadStringTaskAsync(uri); 
    return task.Result; // Result blocks, just like Wait(). 
} 
+0

這是我試過的東西之一,但它仍然掛起,所以可能會有更有趣的事情發生。我已經修改了這個問題以包含新的精簡代碼以及發生了什麼。 – jbhelicon

+0

@jbhelicon:可能是'DownloadStringTaskAsync'本身在UI線程上調度了一些操作。基本上,當你開始做一些你不應該(在這種情況下阻塞UI線程)的東西時,任何假設你「行爲正常」的東西都可能開始失敗。 –

+0

夠公平的,儘管你會認爲這將是一件奇怪的事情。但是我發現WebClient會在UI線程上引發DownloadFileCompleted事件,所以可能就是這樣!有沒有簡單的方法來測試這個猜想?即使用新線程啓動並調用Test,並在完成時恢復調用線程? – jbhelicon