2015-11-09 165 views
1

我已經調整了以下代碼,嘗試從Wasson的asp.net代碼的web api加載。如何測試以確保此代碼真正運行異步?

static public async Task<IEnumerable<T>> ExecuteAsync(HttpClient client, String endPoint) 
    { 
     IEnumerable<T> result = null; 
     HttpResponseMessage response = client.GetAsync(endPoint).Result; 
     response.EnsureSuccessStatusCode(); 
     if (response.IsSuccessStatusCode) 
     { 
      var tResult = await response.Content.ReadAsStringAsync(); 
      result = JsonConvert.DeserializeObject<IEnumerable<T>>(tResult); 
     } 
     return result; 
    } 

當我有它的設計,我覺得這個過程將異步運行,但我不知道如何測試它,以確保它。

我是使用異步編碼的新手,所以任何建議都會有所幫助。

調用過程如下:

public virtual IEnumerable<T> Fill() 
    { 
     IEnumerable<T> result = null; 
     try 
     { 
      using (var client = CreateClient("", new MediaTypeWithQualityHeaderValue("application/json"))) 
      { 

       String _endPoint = "api/" + typeof(T).Name + "/Get"; 

       result = (ExecuteAsync(client, _endPoint)).Result; 
      } 
     } 
     catch (Exception ex) 
     { 
      LogError(ex.Message); 

     } 
     return result; 
    } 

是這個組合可能因爲我希望它異步運行?

我希望能夠異步運行的原因是,填充程序獲取大量的數據庫中的數據的。對於每條記錄來說,更多的情況是大量的單個記錄而不是大的記錄,儘管一些記錄的大小也可能是一個問題。

我不想坐在那裏等待整個頁面與數據庫通信正在發生加載用戶。

這並不重要,在這種情況下,我是否直接連接到數據庫或通過我使用的網絡API會:這需要在某些情況下,無論哪種方式,很長一段時間。

我也很關心死鎖:一個大的取進來,而另一個正在等待。

我最初構圖之後麥克沃森的示例代碼的代碼,卻發現代碼,即使它編譯無限期忌用。

這是否有助於改善情況?

+0

編號'.Result'使其成爲阻塞呼叫。 'Fill'應該標記爲'async',以便您可以調用'result = await ExecuteAsync(client,_endpoint);' –

+0

在Visual Studio中,我相信您的輸出會告訴您何時使用的線程正在退出。這就是我一直看到的,如果異步實際上是創建線程。我的邏輯可能是錯誤的,但如果它沒有在那裏顯示多個線程,那麼我認爲它沒有......並且到目前爲止它是正確的。 – trueCamelType

+0

至於測試一些建議。起初,我陷入陷阱使用'await Task.Delay(TimeInMillisecondsHere)',但後來意識到,你需要一個阻止操作來實際測試,所以現在使用for循環像'for(int i = 0; i kirotab

回答

0

不知道你在這裏後交配。 您發佈的代碼仍然會阻止它所在的線程,因爲您正在調用將阻止的結果。

result = (ExecuteAsync(client, _endPoint)).Result; 

您可以通過讓異步和await關鍵字傳播回最初創建請求的任何方法來使它異步。

public virtual async Task<IEnumerable<T>> Fill() 
{ 
    ... 
    result = await ExecuteAsync(client, _endPoint); 
    ... 
} 

但是我不知道這真的是你追求的,因爲你提到

我不想坐在那裏等待整個頁面而加載用戶與數據庫的通信正在發生。

默認情況下,使事情異步你會不會解決這個問題。完成15秒的操作需要15秒才能完成,無論它是同步還是異步。不同之處在於,如果它是異步的,那麼你的資源效率會更高(這意味着,您可以釋放線程來完成其他任務,同時等待某些內容完成)。

但是,您可以使用任務來實現並行性。舉個例子:

public void DoWork() 
{ 
    Thread.Sleep(10000); 
} 

public void DoMoreWork() 
{ 
    Thread.Sleep(10000); 
} 

如果我們叫這兩個這樣

DoWork(); 
DoMoreWork(); 

然後,將採取20000毫秒秒或20秒 如果我們讓它異步

public async Task DoWork() 
{ 
    await Task.Delay(10000); 
} 

public async Task DoMoreWork() 
{ 
    await Task.Delay(10000); 
} 

和呼叫它是這樣的

await DoWork(); 
await DoMoreWork(); 

然後它仍然需要20秒才能完成。然而,由於DoWork的和DoMoreWork可以從eachothers獨立操作,我們可以在同一時間做

await Task.WhenAll(DoWork(), DoMoreWork()); 

這將(在一個完美的世界)導致這兩個任務運行它們都在10秒內正在做減半時間用戶必須等待。

希望我對這個問題有所瞭解:)