所以我有这个小代码块,它将并行执行多个任务。
// no wrapping in Task, it is async
var activityList = await dataService.GetActivitiesAsync();
// Select a good enough tuple
var results = (from activity in activityList
select new {
Activity = activity,
AthleteTask = dataService.GetAthleteAsync(activity.AthleteID)
}).ToList(); // begin enumeration
// Wait for them to finish, ie relinquish control of the thread
await Task.WhenAll(results.Select(t => t.AthleteTask));
// Set the athletes
foreach(var pair in results)
{
pair.Activity.Athlete = pair.AthleteTask.Result;
}
因此,我正在下载每个给定活动的运动员数据。但也有可能我们多次请求同一位运动员。
我们如何确保 GetAthleteAsync 方法仅在内存缓存中尚未存在的情况下才联机获取实际数据?
目前我尝试使用ConcurrentDictionary<int, Athelete>
在 GetAthleteAsync 方法内
private async Task<Athlete> GetAthleteAsync(int athleteID)
{
if(cacheAthletes.Contains(athleteID))
return cacheAthletes[atheleID];
** else fetch from web
}
你可以改变你的ConcurrentDictionary
缓存Task<Athlete>
而不仅仅是Athlete
。请记住,一个Task<T>
是一个承诺 - 一个最终会产生结果的操作T
。所以,你可以缓存运营代替results.
ConcurrentDictionary<int, Task<Athlete>> cacheAthletes;
然后,你的逻辑将是这样的:如果操作已经在缓存中,则立即(同步)返回缓存的任务。如果不是,则开始下载,将下载操作添加到缓存中,并返回新的下载操作。请注意,所有“下载操作”逻辑都移至另一个方法:
private Task<Athlete> GetAthleteAsync(int athleteID)
{
return cacheAthletes.GetOrAdd(athleteID, id => LoadAthleteAsync(id));
}
private async Task<Athlete> LoadAthleteAsync(int athleteID)
{
// Load from web
}
这样,对同一运动员的多个并行请求将得到相同的结果Task<Athlete>
,每个运动员只下载一次。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)