Last active
March 1, 2020 19:10
-
-
Save divyang4481/1222ef2f01ee4825a5b11b7599d3ac5f to your computer and use it in GitHub Desktop.
Go lang channel like feature in C# .NET
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Chan<T> | |
{ | |
private BlockingCollection<T> _buffer; | |
public Chan() : this(1) { } | |
public Chan(int size) | |
{ | |
_buffer = new BlockingCollection<T>(new ConcurrentQueue<T>(), size); | |
} | |
public bool Send(T t) | |
{ | |
try | |
{ | |
_buffer.Add(t); | |
} | |
catch (InvalidOperationException) | |
{ | |
// will be thrown when the collection gets closed | |
return false; | |
} | |
return true; | |
} | |
public bool Receive(out T val) | |
{ | |
try | |
{ | |
val = _buffer.Take(); | |
} | |
catch (InvalidOperationException) | |
{ | |
// will be thrown when the collection is empty and got closed | |
val = default(T); | |
return false; | |
} | |
return true; | |
} | |
public void Close() | |
{ | |
_buffer.CompleteAdding(); | |
} | |
public IEnumerable<T> Range() | |
{ | |
T val; | |
while (Receive(out val)) | |
{ | |
yield return val; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[TestCase] | |
public void Test_Performance() | |
{ | |
int numItems = 10000000; | |
int numIterations = 10; | |
var stopWatch = new Stopwatch(); | |
stopWatch.Start(); | |
for (int i = 0; i < numIterations; ++i) | |
{ | |
var channel = new Chan<int>(100); | |
var writer = Task.Factory.StartNew(() => { foreach (var num in Enumerable.Range(1, numItems)) { channel.Send(num); } channel.Close(); }); | |
var reader = Task.Factory.StartNew<List<int>>(() => { var res = new List<int>(numItems); foreach (var num in channel.Range()) { res.Add(num); } return res; }); | |
Task.WaitAll(writer, reader); | |
} | |
stopWatch.Stop(); | |
var elapsedMs = stopWatch.Elapsed.TotalMilliseconds; | |
Console.WriteLine(" N = {0}: {1:.00}ms/iteration, {2:.00}ns/item (tx+rx)", numItems, elapsedMs / numIterations, elapsedMs * 1000.0 / numItems / numIterations); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment