Skip to content

Instantly share code, notes, and snippets.

@stdray
Last active March 26, 2019 19:03
Show Gist options
  • Save stdray/d7a60ddeb1b5326347eab578924ff5ec to your computer and use it in GitHub Desktop.
Save stdray/d7a60ddeb1b5326347eab578924ff5ec to your computer and use it in GitHub Desktop.
26.03.2019 21:43:33 | Begin thread 13
26.03.2019 21:43:33 | Begin thread 15
26.03.2019 21:43:33 | Begin thread 14
26.03.2019 21:43:33 | Begin thread 16
26.03.2019 21:43:33 | Process account account_6 in thread 16
26.03.2019 21:43:33 | Process account account_7 in thread 14
26.03.2019 21:43:33 | Process account account_4 in thread 15
26.03.2019 21:43:33 | Process account account_5 in thread 13
26.03.2019 21:43:33 | Process account account_3 in thread 16
26.03.2019 21:43:33 | Process account account_2 in thread 14
26.03.2019 21:43:35 | Process account account_1 in thread 16
26.03.2019 21:43:36 | Process account account_1 locked for time: 26.03.2019 21:45:20
26.03.2019 21:43:36 | Process account account_8 in thread 16
26.03.2019 21:43:37 | Process account account_6 in thread 15
26.03.2019 21:43:37 | Process account account_7 in thread 13
26.03.2019 21:43:37 | Process account account_3 in thread 14
26.03.2019 21:43:38 | Process account account_5 in thread 15
26.03.2019 21:43:39 | Process account account_4 in thread 15
26.03.2019 21:43:40 | Process account account_2 in thread 15
26.03.2019 21:43:40 | Process account account_6 in thread 16
26.03.2019 21:43:40 | Process account account_5 in thread 14
26.03.2019 21:43:41 | Process account account_4 in thread 15
26.03.2019 21:43:41 | Process account account_7 locked for time: 26.03.2019 21:45:06
26.03.2019 21:43:41 | Process account account_8 in thread 13
26.03.2019 21:43:41 | Process account account_3 in thread 13
26.03.2019 21:43:42 | Process account account_2 in thread 15
26.03.2019 21:43:44 | Process account account_8 in thread 13
26.03.2019 21:43:44 | Process account account_4 in thread 14
26.03.2019 21:43:44 | Process account account_3 in thread 16
26.03.2019 21:43:45 | Process account account_5 in thread 14
26.03.2019 21:43:46 | Process account account_5 locked for time: 26.03.2019 21:45:29
26.03.2019 21:43:46 | Process account account_6 in thread 14
26.03.2019 21:43:46 | Process account account_4 in thread 15
26.03.2019 21:43:46 | Process account account_2 in thread 14
26.03.2019 21:43:47 | Process account account_6 in thread 16
26.03.2019 21:43:47 | Process account account_3 in thread 16
26.03.2019 21:43:48 | Process account account_8 locked for time: 26.03.2019 21:44:14
26.03.2019 21:43:48 | Process account account_6 in thread 13
26.03.2019 21:43:49 | Process account account_4 in thread 15
26.03.2019 21:43:49 | Process account account_2 in thread 14
26.03.2019 21:43:50 | Process account account_6 in thread 13
26.03.2019 21:43:51 | Process account account_3 locked for time: 26.03.2019 21:45:04
26.03.2019 21:43:51 | Process account account_2 in thread 16
26.03.2019 21:43:53 | Process account account_6 locked for time: 26.03.2019 21:44:00
26.03.2019 21:43:53 | Process account account_4 locked for time: 26.03.2019 21:44:25
26.03.2019 21:43:53 | Process account account_2 in thread 14
26.03.2019 21:43:57 | Process account account_2 in thread 13
26.03.2019 21:43:58 | Process account account_2 in thread 14
26.03.2019 21:44:00 | Process account account_6 in thread 13
26.03.2019 21:44:00 | Process account account_2 in thread 15
26.03.2019 21:44:02 | Process account account_2 in thread 16
26.03.2019 21:44:03 | Process account account_6 in thread 14
26.03.2019 21:44:03 | Process account account_6 in thread 15
26.03.2019 21:44:03 | Process account account_6 in thread 13
26.03.2019 21:44:03 | Process account account_2 in thread 14
26.03.2019 21:44:06 | Process account account_6 in thread 15
26.03.2019 21:44:06 | Process account account_2 in thread 16
26.03.2019 21:44:07 | Process account account_6 in thread 13
26.03.2019 21:44:07 | Process account account_6 in thread 14
26.03.2019 21:44:08 | Process account account_6 in thread 15
26.03.2019 21:44:08 | Process account account_2 in thread 13
26.03.2019 21:44:09 | Process account account_2 in thread 14
26.03.2019 21:44:10 | Process account account_2 in thread 16
26.03.2019 21:44:11 | Process account account_6 in thread 13
26.03.2019 21:44:13 | Process account account_6 in thread 14
26.03.2019 21:44:14 | Process account account_8 in thread 13
26.03.2019 21:44:14 | Process account account_6 in thread 15
26.03.2019 21:44:14 | Process account account_2 in thread 14
26.03.2019 21:44:15 | Process account account_2 locked for time: 26.03.2019 21:44:31
26.03.2019 21:44:17 | Process account account_8 locked for time: 26.03.2019 21:47:10
26.03.2019 21:44:18 | Process account account_6 in thread 16
26.03.2019 21:44:19 | Process account account_6 in thread 13
26.03.2019 21:44:21 | Process account account_6 locked for time: 26.03.2019 21:45:11
26.03.2019 21:44:25 | Process account account_4 in thread 13
26.03.2019 21:44:29 | Process account account_4 in thread 14
26.03.2019 21:44:30 | Process account account_4 in thread 15
26.03.2019 21:44:30 | Process account account_4 in thread 16
26.03.2019 21:44:31 | Process account account_4 in thread 13
26.03.2019 21:44:31 | Process account account_2 in thread 14
26.03.2019 21:44:34 | Process account account_4 in thread 15
26.03.2019 21:44:34 | Process account account_2 in thread 16
26.03.2019 21:44:35 | Process account account_4 in thread 13
26.03.2019 21:44:37 | Process account account_2 in thread 14
26.03.2019 21:44:37 | Process account account_2 in thread 15
26.03.2019 21:44:37 | Process account account_2 in thread 16
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
namespace ConsoleApp1
{
public class Program
{
static readonly Random Rng = new Random();
const int WorkerCount = 4;
const int AccountCount = 8;
public static void Main()
{
var cancelSource = new CancellationTokenSource();
var context = new Context
{
WaitQueue = new ConcurrentDictionary<string, Account>(),
WorkQueue = new ConcurrentQueue<Account>(),
Cancel = cancelSource.Token
};
for (var i = 0; i < WorkerCount; i++)
new Thread(ProcessWorkQueue).Start(context);
new Thread(ProcessWaitQueue).Start(context);
for (var i = 0; i < AccountCount; i++)
{
var id = $"account_{i + 1}";
context.WaitQueue.TryAdd(id, new Account {Id = id});
}
Thread.Sleep(60_000);
cancelSource.Cancel();
}
static void ProcessWaitQueue(object obj)
{
var context = (Context) obj;
while (!context.Cancel.IsCancellationRequested)
{
var ids = context.WaitQueue.Values
.Where(a => a.AvailableFrom < DateTime.Now)
.OrderBy(x => x.LastActivity)
.Select(x => x.Id)
.ToList();
if (!ids.Any())
Thread.Sleep(100);
foreach (var id in ids)
if (context.WaitQueue.TryRemove(id, out var account))
context.WorkQueue.Enqueue(account);
}
}
static void ProcessWorkQueue(object obj)
{
var context = (Context) obj;
Console.WriteLine("{0} | Begin thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
while (!context.Cancel.IsCancellationRequested)
{
if (context.WorkQueue.TryDequeue(out var account))
{
Console.WriteLine("{0} | Process account {1} in thread {2}", DateTime.Now, account.Id,
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(Rng.Next(0, 5) * 1000);
if (Rng.Next() % 5 == 0)
{
account.AvailableFrom = DateTime.Now.AddSeconds(Rng.Next(0, 200));
Console.WriteLine("{0} | Process account {1} locked for time: {2}", DateTime.Now, account.Id,
account.AvailableFrom);
}
account.LastActivity = DateTime.Now;
if (!context.WaitQueue.TryAdd(account.Id, account))
throw new InvalidOperationException("conflict");
}
else
{
Thread.Sleep(100);
}
}
Console.WriteLine("{0} | End thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
}
}
class Context
{
public ConcurrentQueue<Account> WorkQueue { get; set; }
public ConcurrentDictionary<string, Account> WaitQueue { get; set; }
public CancellationToken Cancel { get; set; }
}
class Account
{
public string Id { get; set; }
public DateTime AvailableFrom { get; set; } = DateTime.MinValue;
public DateTime LastActivity { get; set; } = DateTime.MinValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment