Task.FromResult
字數:889字
預計閱讀時間:3分鍾
1.解釋
官方定義:創建一個結果的、成功完成的Task<TResult>
。
public static System.Threading.Tasks.Task<TResult> FromResult<TResult> (TResult result);
可以看出,Task.FromResult( )方法接受一個TResult
然后返回一個Task<TResult>
。
2.例子
使用 Task.FromResult
方法檢索緩存中保存的異步下載操作的結果。
Ex:
以下示例從Web下載字符串。它定義了DownloadStringAsync
方法。此方法異步從Web下載字符串。此示例還使用ConcurrentDictionary <TKey,TValue>
對象來緩存先前操作的結果。如果輸入地址保存在此緩存中,則DownloadStringAsync
使用FromResult
方法生成一個Task <TResult>
對象,該對象保存該地址的內容。否則,DownloadStringAsync
從Web
下載文件並將結果添加到緩存中。
1.添加CachedDownloads類,並且定義方法:
class CachedDownloads
{
/// <summary>
/// 將下載在操作的結果保存在線程安全集合cachedDownloads中
/// </summary>
static ConcurrentDictionary<string, string> cachedDownloads = new ConcurrentDictionary<string, string>();
/// <summary>
/// 以字符串的形式異步下載所請求的資源
/// </summary>
/// <param name="address">地址</param>
/// <returns></returns>
public static Task<string> DownloadStringAsync(string address)
{
//首先嘗試從緩存中檢索內容。
string content;
if (cachedDownloads.TryGetValue(address, out content))
{
return Task.FromResult<string>(content);
}
//如果結果不在緩存中,那么使用異步方法下載字符串,並將其添加到緩存中
return Task.Run(async () =>
{
content = await new WebClient().DownloadStringTaskAsync(address);
cachedDownloads.TryAdd(address, content);
return content;
});
}
}
該類定義了一個ConcurrentDictionary
集合用以保存下載結果,並且定義了DownloadStringAsync
接受一個字符串地址,該方法內首先嘗試從緩存中檢索內容,如果結果不在緩存中,那么使用異步方法下載字符串,並將其添加到緩存中,返回Task<string>
結果。
2.Main方法:
class Program
{
static void Main(string[] args)
{
//需要下載的url集合
string[] urls = new string[] {
"https://www.cnblogs.com",
"http://msdn.microsoft.com",
"http://www.microsoft.com"
};
//用於計時下載操作
Stopwatch stopwatch = new Stopwatch();
//開始計時下載url所需要的時間
stopwatch.Start();
var downloads = from url in urls
select CachedDownloads.DownloadStringAsync(url);
Task.WhenAll(downloads).ContinueWith(results =>
{
stopwatch.Stop();
//打印下載的字符數和運行時間。
Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
results.Result.Sum(result => result.Length),
stopwatch.ElapsedMilliseconds);
}).Wait();
//重新計時
stopwatch.Restart();
downloads = from url in urls
select CachedDownloads.DownloadStringAsync(url);
Task.WhenAll(downloads).ContinueWith(results =>
{
stopwatch.Stop();
//打印下載的字符數和運行時間。
Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
results.Result.Sum(result => result.Length),
stopwatch.ElapsedMilliseconds);
}).Wait();
Console.ReadKey();
}
}
測試結果:
3.結論
此示例計算兩次下載多個字符串所需的時間。第二組下載操作應該比第一組少花費時間,因為結果保存在緩存中。該FromResult
方法使DownloadStringAsync
創建方法任務<TResult>
持有這些預先計算的結果對象。
我對“預先”的理解為已經知道的結果,當一個方法需要返回Task
參考資料: