Skip to content

Instantly share code, notes, and snippets.

@juner
Created May 30, 2018 01:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juner/cee3c83360f8d5434e0ebb68cda63294 to your computer and use it in GitHub Desktop.
Save juner/cee3c83360f8d5434e0ebb68cda63294 to your computer and use it in GitHub Desktop.
Code that works in .net frameworks 4.5, but not in Theraot.Core in .net frameworks 3.5
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var source = new CancellationTokenSource(TimeSpan.FromSeconds(100));
var semaphore = new SemaphoreSlim(0, 3);
System.Diagnostics.Debug.WriteLine($"{semaphore.CurrentCount} task can enter the semaphore.");
int padding = 0;
Task[] tasks = Enumerable.Range(0, 4)
.Select(index =>
{
return Task.Factory.StartNew(async () =>
{
var CurrentId = Task.CurrentId;
System.Diagnostics.Debug.WriteLine($"Task {CurrentId} begins and waits for the semaphore.");
await semaphore.WaitAsync(source.Token);
Interlocked.Add(ref padding, 100);
System.Diagnostics.Debug.WriteLine($"Task {CurrentId} enters the semaphore.");
Thread.Sleep(1000 + padding);
System.Diagnostics.Debug.WriteLine($"Task {CurrentId} release the semaphore; previous count: {semaphore.Release()} ");
}).Unwrap();
}).ToArray();
Thread.Sleep(TimeSpan.FromMilliseconds(500));
System.Diagnostics.Debug.WriteLine($"Main thread call Release(3) -->");
semaphore.Release(3);
System.Diagnostics.Debug.WriteLine($"{semaphore.CurrentCount} tasks can enter the semaphore.");
Task.WaitAll(tasks, source.Token);
System.Diagnostics.Debug.WriteLine("Main thread exits");
}
}
}
@theraot
Copy link

theraot commented Jun 7, 2018

In the line
System.Diagnostics.Debug.WriteLine($"Task {CurrentId} release the semaphore; previous count: {semaphore.Release()} ");

The system will execute semaphore.Release() before writing the message. If the thread is preempted in that moment, another thread thread may have time to resume advance to System.Diagnostics.Debug.WriteLine($"Task {CurrentId} enters the semaphore."); and result in the messages out of order.

That is a marginal case I will not be able to fix. The thing is, it is hard to tell if have fixed the other problems if I am getting false results from this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment