using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
public static ConcurrentDictionary<int, byte> PROCESSED = new ConcurrentDictionary<int, byte>();
static void Main(string[] args)
var services = new ServiceCollection();
services.AddMemoryCache();
services.AddTransient<JobService>();
services.AddTransient<MyCacheService>();
services.AddTransient<Worker>();
var serviceProvider = services.BuildServiceProvider();
var workers = Enumerable.Range(1, 100)
var w = serviceProvider.GetService<Worker>();
w.Skills = new int[] { 1, 2 };
var masterWorkers = Enumerable.Range(101, 100)
var w = serviceProvider.GetService<Worker>();
w.Skills = new int[] { 4, 5 };
workers.AddRange(masterWorkers);
var start = DateTime.Now;
Parallel.ForEach(workers, (w) =>
Console.WriteLine("Total Time {0}", end.Subtract(start));
Console.WriteLine("Total Processed {0}", PROCESSED.Count);
Console.WriteLine("Press any key");
public class MyCacheService
private readonly IMemoryCache _memoryCache = null;
static object myLock = new object();
public MyCacheService(IMemoryCache memoryCache)
_memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
public Job Find(int key, string title, int[] skills, Func<int, List<Job>> getJobs)
List<Job> cachedJobs = null;
if (!_memoryCache.TryGetValue(key, out cachedJobs))
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(30));
cachedJobs = _memoryCache.Set(key, jobs, cacheEntryOptions);
var job = cachedJobs.Where(j => j.Title == title &&
!j.Skills.Except(skills).Any())
private readonly MyCacheService _cacheService;
private readonly JobService _jobService;
public Worker(MyCacheService cacheService, JobService jobService)
_cacheService = cacheService;
_jobService = jobService;
var start = DateTime.Now;
var job = _cacheService.Find(WorkItemID, Title, Skills, _jobService.GetJobs);
Program.PROCESSED.TryAdd<int, byte>(job.JobID, 1);
Console.WriteLine("Job ID: {0}, WorkerID: {1}, Title:{2}, Time:{3}", job.JobID, WorkerID, Title, end.Subtract(start));
public List<Job> GetJobs(int workItemID)
List<Job> jobs = new List<Job>();
for (int i = 0; i < 5000; i++)
Skills = new int[] { 1, 2 }
for (int i = 0; i < 5000; i++)
public int JobID { get; set; }
public string Title { get; set; }
public int[] Skills { get; set; }