SilverShade
SilverShade
Explore posts from servers
CC#
Created by SilverShade on 11/11/2024 in #help
Uncaught OperationCancelledException when shutting down IHostedService
Hmm yeah i’ll try to implement that, thanks!♥️
53 replies
CC#
Created by SilverShade on 11/11/2024 in #help
Uncaught OperationCancelledException when shutting down IHostedService
So yeah it best describes what is implemented in my code
53 replies
CC#
Created by SilverShade on 11/11/2024 in #help
Uncaught OperationCancelledException when shutting down IHostedService
Ig if i were to write pseudo code for it, the snippet i just sent would be it
53 replies
CC#
Created by SilverShade on 11/11/2024 in #help
Uncaught OperationCancelledException when shutting down IHostedService
Yeah it’s not in my app
53 replies
CC#
Created by SilverShade on 11/11/2024 in #help
Uncaught OperationCancelledException when shutting down IHostedService
public abstract class BackgroundService : IHostedService
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();

protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}

public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
return;

try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public abstract class BackgroundService : IHostedService
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();

protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}

public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
return;

try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
Cant share the original code since it’s proprietary, but the logic is roughly the same as here, taken from an open source article
53 replies
CC#
Created by SilverShade on 2/20/2024 in #help
ThreadPool implementation with WSQ
private bool TryGetFromLocalQueue(out Action task)
{
task = null;
return _localQueues[Environment.CurrentManagedThreadId].LocalPop(ref task);
}

private bool TryGetFromGlobalQueue(out Action task)
{
lock (_globalQueue)
return _globalQueue.TryDequeue(out task);
}

private bool TrySteal(out Action task)
{
task = null;
var currentThreadId = Environment.CurrentManagedThreadId;
foreach (var (threadId, queue) in _localQueues)
{
if (threadId == currentThreadId || !queue.TrySteal(ref task))
continue;

return true;
}

return false;
}
private bool TryGetFromLocalQueue(out Action task)
{
task = null;
return _localQueues[Environment.CurrentManagedThreadId].LocalPop(ref task);
}

private bool TryGetFromGlobalQueue(out Action task)
{
lock (_globalQueue)
return _globalQueue.TryDequeue(out task);
}

private bool TrySteal(out Action task)
{
task = null;
var currentThreadId = Environment.CurrentManagedThreadId;
foreach (var (threadId, queue) in _localQueues)
{
if (threadId == currentThreadId || !queue.TrySteal(ref task))
continue;

return true;
}

return false;
}
3 replies
CC#
Created by SilverShade on 2/20/2024 in #help
ThreadPool implementation with WSQ
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using CustomThreadPool.Collections;

namespace CustomThreadPool.ThreadPools;

public class MyThreadPool : IThreadPool
{
private long _processedTask;
private readonly Queue<Action> _globalQueue = new();
private readonly ReadOnlyDictionary<int, WorkStealingQueue<Action>> _localQueues;

private const int WorkerCount = 10;

public MyThreadPool()
{
var workers = new Thread[WorkerCount];

var queues = new Dictionary<int, WorkStealingQueue<Action>>();
for (var i = 0; i < WorkerCount; i++)
{
var worker = new Thread(Worker) {IsBackground = true};
workers[i] = worker;
queues.Add(worker.ManagedThreadId, new WorkStealingQueue<Action>());
}

_localQueues = new ReadOnlyDictionary<int, WorkStealingQueue<Action>>(queues);

foreach (var worker in workers)
worker.Start();
}

public void EnqueueAction(Action action)
{
if (_localQueues.TryGetValue(Environment.CurrentManagedThreadId, out var localQueue))
{
localQueue.LocalPush(action);
return;
}

lock (_globalQueue)
{
_globalQueue.Enqueue(action);
Monitor.Pulse(_globalQueue);
}
}

public long GetTasksProcessedCount() => _processedTask;

private void Worker()
{
while (true)
{
if (TryGetFromLocalQueue(out var work)
|| TryGetFromGlobalQueue(out work)
|| TrySteal(out work))
{
work();
Interlocked.Increment(ref _processedTask);
continue;
}

lock (_globalQueue)
Monitor.Wait(_globalQueue);
}

// ReSharper disable once FunctionNeverReturns
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using CustomThreadPool.Collections;

namespace CustomThreadPool.ThreadPools;

public class MyThreadPool : IThreadPool
{
private long _processedTask;
private readonly Queue<Action> _globalQueue = new();
private readonly ReadOnlyDictionary<int, WorkStealingQueue<Action>> _localQueues;

private const int WorkerCount = 10;

public MyThreadPool()
{
var workers = new Thread[WorkerCount];

var queues = new Dictionary<int, WorkStealingQueue<Action>>();
for (var i = 0; i < WorkerCount; i++)
{
var worker = new Thread(Worker) {IsBackground = true};
workers[i] = worker;
queues.Add(worker.ManagedThreadId, new WorkStealingQueue<Action>());
}

_localQueues = new ReadOnlyDictionary<int, WorkStealingQueue<Action>>(queues);

foreach (var worker in workers)
worker.Start();
}

public void EnqueueAction(Action action)
{
if (_localQueues.TryGetValue(Environment.CurrentManagedThreadId, out var localQueue))
{
localQueue.LocalPush(action);
return;
}

lock (_globalQueue)
{
_globalQueue.Enqueue(action);
Monitor.Pulse(_globalQueue);
}
}

public long GetTasksProcessedCount() => _processedTask;

private void Worker()
{
while (true)
{
if (TryGetFromLocalQueue(out var work)
|| TryGetFromGlobalQueue(out work)
|| TrySteal(out work))
{
work();
Interlocked.Increment(ref _processedTask);
continue;
}

lock (_globalQueue)
Monitor.Wait(_globalQueue);
}

// ReSharper disable once FunctionNeverReturns
}
3 replies