Skip to content

Instantly share code, notes, and snippets.

@INTERNALINTERFERENCE
Created November 23, 2022 03:03
Show Gist options
  • Save INTERNALINTERFERENCE/5fa308bc97815d548acee8fd3a1ed74b to your computer and use it in GitHub Desktop.
Save INTERNALINTERFERENCE/5fa308bc97815d548acee8fd3a1ed74b to your computer and use it in GitHub Desktop.
namespace testchannels
{
internal class Program
{
private static BlockingCollection<Action> _queue = new();
private static CancellationTokenSource _currentCts;
private static object _sync = new();
static async Task Main(string[] args)
{
var queueProcessingTask = Task.Run(QueueProcessor);
_queue.Add(
() => SetStateOn(TimeSpan.FromSeconds(5),
() => SetStateOff(TimeSpan.FromSeconds(3))));
_queue.Add(() => Console.WriteLine("print last task"));
var key = Console.ReadKey().Key;
if (key == ConsoleKey.C)
{
Kill();
}
_queue.CompleteAdding();
await queueProcessingTask;
}
private static void SetStateOn(TimeSpan delay, Action cancelledAction)
{
lock (_sync)
{
_currentCts = new CancellationTokenSource();
}
var token = _currentCts.Token;
DoWork(token, delay, cancelledAction);
}
private static void SetStateOff(TimeSpan delay)
{
lock (_sync)
{
_currentCts = new CancellationTokenSource(delay);
}
var token = _currentCts.Token;
DoAnotherWork(token);
}
private static void QueueProcessor()
{
foreach (var action in _queue.GetConsumingEnumerable())
{
action();
}
}
private static void Kill()
{
//while (_queue.TryTake(out _)) { }
lock (_sync)
{
_currentCts?.Cancel();
}
}
private static void DoWork(
CancellationToken ct, TimeSpan delay, Action cancelledAction)
{
DateTime endAt = DateTime.Now.Add(delay);
while (DateTime.Now < endAt)
{
if (ct.IsCancellationRequested)
{
cancelledAction.Invoke();
return;
}
Console.WriteLine("...");
}
}
private static void DoAnotherWork(
CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
Console.WriteLine("!!!");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment