The best way to do this is load your list of work, randomize the list, then put the list in to a queue of some form to be pulled out by the end workers.
private BlockingCollection<string> GetWorkSoruce()
{
List<string> sourceList = GetListOfFiles(); //How you get your list is up to you.
Shuffle(sourceList); //see http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp
//Create a thread safe queue that many consumers can pull from.
var collection = BlockingCollection<string>(new ConcurrentQueue<string>(sourceList));
collection.CompleteAdding();
return collection;
}
Now each of your workers (Users) can pull out of the queue and be given work to do. Because the queue is a ConcurrentQueue you can have many workers from many threads all working at the same time.
private void WorkerDoWork(BlockingCollection<string> workSource, int itemsToTake)
{
foreach(var imagePath in workSource.GetConsumingEnumerable().Take(itemsToTake))
{
ProcessImage(imagePath);
}
}