2011-12-20 47 views
12

我有一個負責檢索資源的類,該資源同樣緩存它們以便快速訪問。 類公開了用來檢索資源異步方法:如何使用任務有條件地異步運行代碼

public Task<object> GetResourceAsync(string resourceName) 
{ 
    return Task.Factory.StartNew<object>(() => 
    { 
     // look in cache 

     // if not found, get from disk 

     // return resource 
    }); 
} 

客戶端代碼然後看起來是這樣的:

myResourceProvider.GetResourceAsync("myResource") 
    .ContinueWith<object>(t => Console.WriteLine("Got resource " + t.Result.ToString())); 

這樣,總是用一個後臺線程。但是,如果在緩存中找到對象,我不希望代碼異步運行。 如果它在緩存中找到,我想立即返回資源,而不必使用另一個線程。

謝謝。

回答

19

.NET 4.5有Task.FromResult,它允許您返回一個Task<T>,但不是在線程池線程上運行委託,而是顯式設置任務的返回值。

在你的代碼的情況下

所以:

public Task<object> AsyncGetResource(string resourceName) 
{ 
    object valueFromCache; 
    if (_myCache.TryGetValue(resourceName, out valueFromCache)) { 
     return Task.FromResult(valueFromCache); 
    } 
    return Task.Factory.StartNew<object>(() => 
    { 
     // get from disk 
     // add to cache 
     // return resource 
    }); 
} 

如果你仍然在.NET 4.0中,你可以使用TaskCompletionSource<T>做同樣的事情:

var tcs = new TaskCompletionSource<object>(); 
tcs.SetResult(...item from cache...); 
return tcs.Task; 
+0

這正是我正在尋找。謝謝! – 2011-12-20 13:23:32

+0

+1我在問這個問題(http://stackoverflow.com/questions/15316613/real-life-scenarios-for-using-taskcompletionsourcet),現在我可以看到我應該什麼時候使用它。 – 2013-03-10 06:38:37

+0

@joe您可以請爲Task.FromResult增強此代碼(附加解決方案)嗎? – 2013-06-27 07:44:38