6

if (TaskCancellation == true) { break; } CancellationToken.ThrowIfCancellationRequested(); Some comments explaining why two different cancellation methods are necessary would be useful. if (jockey.Name != null) { lock (((...


5

Dispose the scheduler gracefully As you mentioned, you lack proper disposal functionality. void Run() { while (!m_disposed) { var task = m_taskQueue.Take(); Debug.Assert(TryExecuteTask(task)); } } The first issue is that bool m_disposed is not marked as volatile. This means that this variable is subject to optimisations that could ...


3

I would first start by saying that such a class is generally regarded as a bad practice because it doesn't achieve what's supposed to do, or simply there are better ways of doing it. But let's go to the actual code, in the ConnectAsync method. var connectionTask = Task.Run(() => { try { var _loader = new DatabaseDriverLoader(); ...


3

Concurrency Is this parallel implementation correct? I would expect a method called RunParallel<T> to use processor affinity (Parallel.For) specially since you take the processor count into account var tasks = new Task<Maybe<T>>[Environment.ProcessorCount];. But instead, you use thread affinity tasks[i] = Task.Run(() => .. Either ...


3

Readability Use keyword var any time that the initialization of the variable clearly tells what the variable represents. Avoid abbreviations in variable names. var messageQueue = new MessageQueue(queue); var semaphore = new SemaphoreSlim(15, 15); Configuration Avoid hard-coded settings: var semaphore = new SemaphoreSlim(15, 15); Make use of a pattern ...


3

Review Is there a better way to safely manage the cancellation and disposal of SemaphoreSlim instances? You've made a pattern to safely manage completing / aborting a task that is acquiring or has acquired a lock on a semaphore, not to safely manage the cancellation and disposal of SemaphoreSlim instances. You should only release the semaphore if you are ...


3

Foreword I appreciate you taking the effort to edit your question time and again to clarify your goal. At first, I thought you were making a synchronous task scheduler using whatever thread is available at any given time, which would have been really cool as well! In fact, your smartly designed API could be augmented to become one if you allow: chaining ...


2

Except all that @JAD said, which I totally agree with. I will give me five cents also after taking your comment in mind. I want to cancel the other pings when one of the ping responses is successful. This should be the default behaviour - so I don't want to expose this implementation detail to the other clients. First and foremost, there is a much ...


2

It doesn't make sense to have the CancellationTokenSource private like you have now. Who is going to be able to cancel the operation? The user of your class can't access the source or provide their own token. The class doesn't offer any API to cancel. Instead, you should alter the private bool IsOneOfTheHostsAvailable() method to accept a CancellationToken ...


2

Task Parallel Library (TPL) I believe you are reinventing the wheel here. TPL provides numerous ways of synchronizing tasks. For instance, it allows you to: create a task scheduler from current synchronization context or to start a task on a specified task scheduler. All you need to do is create a custom synchronization context (.NET Core no longer ...


1

You definitely should remove all Console.WriteLine operations that are executed during the measuring. You want to measure pure excecution time. Also thread creation/management costs time i.e. overhead. When using Thread (executing PrintLoopWithThread) you started the Stopwatch BEFORE you created the threads, which is correct, because you want to include ...


1

The Console uses synchronization: I/O operations that use these streams are synchronized, which means that multiple threads can read from, or write to, the streams. This synchronization ensures that all sentences are printed and nothing gets lost due to a data race. However, synchronization kills multithreading, because the threads will stop at the ...


1

Values of the Base class should have protected set;. In Mesh there is inconsistency with properties. Most are not readonly while some are. Depending of whether or not those properties should be readonly you may remove Values initialization as well as xn and yn computation from Compute. Furthermore, regardless of previous points, depending on whether or ...


1

Just some thoughts: Not sure why you don't just flatten the expression tree with a visitor and then return the collection of expressions. This leads to simpler code: class Program { static void Main(string[] args) { Expression<Func<int, int, int>> expr = (a, b) => ((a + b) * (a - b)); //Flatten the entire tree. ...


1

Race Condition You are starting two tasks concurrently, each blocking on an event to occur. var res = await Task.WhenAny(ReadAsync(stream, buffer, ct), GetPayload(ct)); By calling WhenAny, once one of tasks is completed, you continue without awaiting completion of the other task. Let's say that ReadAsync completes first, this means the following code rus ...


1

While continuing work on this code I have noticed that ListNonArchiveDirectoresWithFiles() already collects all the data retrieved by ListFilesInDirectories() and those methods could be one. I have also came across [Toub Stephen (2010). Patterns for Parallel Programming, Microsoft]. This book contains a very clear and concise implementation of ...


1

Specification There are a couple of strategies available to you depending on what exactly you mean with "not spinning up too many concurrent tasks" Possible Strategies If you want a maximum allowed number of tasks to be processed concurrently on the server, regardless of this method, assuming you are using the default task scheduler, you can set the ...


1

Blocking code in a loop You are starting your tasks asynchronously.. Task.Factory.StartNew(() only to block synchronously inside the loop.. allLinks.Add(task.Result.ToList()); resulting in sequentially starting and awaiting the intermediate results for each cycle in the loop. foreach (string rootUrl in rootUrls) { // .. code ...


Only top voted, non community-wiki answers of a minimum length are eligible