-
Notifications
You must be signed in to change notification settings - Fork 14
Example IdGenerator Usage and ThreadPool Tests
piranout edited this page Jun 30, 2015
·
1 revision
This is a complete program that will:
- Show how to use the Id Generator
- Test it for performance
- Verify thread safety
- Ensure Ids are collision-free.
Just add the NuGet Package, paste the entire class below into the Program.cs of a new console app, and run it.
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Funcular.IdGenerators.Base36;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
TestDefaultConstructor();
TestSpecificConstructor();
TestMultithreading(seconds: 10);
Console.Write("Press any key to exit. ");
Console.ReadKey(true);
}
private static void TestDefaultConstructor()
{
var generator = new Base36IdGenerator();
Console.WriteLine("Id from default constructor: {0}", generator.NewId());
Console.WriteLine("Delimited Id from same: {0}", generator.NewId(true));
Console.WriteLine();
}
private static void TestSpecificConstructor()
{
var generator = new Base36IdGenerator(12, 6, 7, "", "-", new[] {20, 15, 10, 5});
Console.WriteLine("Id from 25-char constructor: {0}", generator.NewId());
Console.WriteLine("Delimited Id from same: {0}", generator.NewId(true));
Console.WriteLine();
}
private static void TestMultithreading(int seconds = 10)
{
var ids = new ConcurrentDictionary<string, string>();
var threadIds = new ConcurrentDictionary<int, int>();
var tokenSource = new CancellationTokenSource();
Console.WriteLine("Starting collision, thread safety and performance test.");
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(state => MakeIdsUntilCancel(ids, threadIds, tokenSource));
}
while (sw.Elapsed.Seconds < seconds)
{
Console.Write(".");
Thread.Sleep(250);
}
tokenSource.Cancel();
Console.WriteLine();
Console.WriteLine(
"Thread pool produced {0:n0} ids using {1} threads in {2}\r\n({3:n0}/sec) with no collisions. Id length is {4}.",
ids.Count,
threadIds.Count,
sw.Elapsed,
((double)ids.Count / (double)sw.ElapsedMilliseconds) * 1000,
ids.First().Key.Length);
Console.WriteLine();
}
private static void MakeIdsUntilCancel(ConcurrentDictionary<string, string> ids, ConcurrentDictionary<int, int> threadIds, CancellationTokenSource tokenSource)
{
var generator = new Base36IdGenerator();
while (tokenSource.IsCancellationRequested == false)
{
if (!ids.TryAdd(generator.NewId(), ""))
throw new Exception(string.Format("Id collision after {0:n0} Ids!", ids.Count));
threadIds.TryAdd(Thread.CurrentThread.ManagedThreadId, 0);
}
}
}
}