2013-11-15 63 views
0

我對於異步C#編碼非常新,對於Azure表,可以選擇同步+異步調用。假設1)我必須在我的方法中獲取一個實體,並且2)線程在此期間沒有其他任何可以執行的操作,是否有任何理由使用下面的異步版本的代碼?它是否會將吞吐量增加到我的多線程應用程序,通過釋放線程來處理不同的事情。不確定同步調用有多深「阻塞」了事情。我知道有時可能需要300多毫秒才能從天藍色表格獲得響應。azure表API - 我應該使用ExecuteAsync

對於上下文,我編寫了Photon套接字服務器實現 - 它使用線程池和Fibers。我採取這樣的接口(沒有異步事件) protected override void OnOperationRequest(OperationRequest o, SendParameters p) 我可以做的,但是使用異步調用的光子是這樣的:requestFiber.Enqueue(() => DoStuff;);

/* synchronous version of code fragment */ 

entity = tableRetryPolicy.ExecuteAction(() => { 
    var result = table.Execute (retrieveOp); 
    if(result.HttpStatusCode == 404) 
    return null; 
    App.CheckHttpStatusCode ("Get (Table) Retrieve", result, 200); 
    return (T) result.Result; 
}); 

/* async version of code fragment */ 
var task = tableRetryPolicy.ExecuteAsync(() => 
    table.ExecuteAsync (retrieveOp).ContinueWith(t => 
    { 
     if (t.Exception != null) 
     { 
     // non-transient exception occurred or retry limit reached 
     App.log.Error("Get (Table) failed all retries: entityId: " + entityId); 
     } 
     else 
     { 
     if(t.Result.HttpStatusCode == 404) 
      return; 
     App.CheckHttpStatusCode ("Get (Table) Retrieve", t.Result, 200); 
     entity = (T) t.Result.Result; 
     } 
    } 
)); 
task.Wait(); 
//^dont have anything else we can do with this execution path, except wait! 

回答

1

這更是一個普通的.Net線程問題。暴露的存儲API是真正的同步和異步的,這意味着Sync方法將阻塞調用線程並在該線程上執行所有工作,而異步方法不會阻塞和使用IO完成端口/ calblacks。異步存儲API還允許先佔式取消,以及先發制人的超時,這可以在您有嚴格的性能要求時提供幫助(請參閱請求選項超時屬性)。

要考慮的最大問題是您的應用程序需要消耗多少線程。不管使用什麼實現/堆棧,每個請求使用1個線程只會擴展到最多幾千個併發請求,因爲您將花費更多時間/內存交換線程。 (這對緩存來說也不是很好)。關於線程的觀點差異很大,但是對於真正的高性能/高規模應用來說,使用少量線程(大致邏輯處理器數量的兩倍)的實現和異步請求將比具有多個線程的同步更高且更線性實現。

+0

謝謝喬!因此,爲了解釋並確保我明白了 - 在上面的代碼示例中,task.Wait()將釋放線程以可能執行其他工作,而table.Execute()將絕對阻止該線程? –