public void RunThread() { ThreadFiber threadFiber = new ThreadFiber(new CommandQueue()); threadFiber.Start(); threadFiber.Dispose(); threadFiber.Join(); }
public void BatchingWithKey() { using (var fiber = new ThreadFiber()) { fiber.Start(); var counter = new Channel<int>(); var reset = new ManualResetEvent(false); Action<IDictionary<String, int>> cb = delegate(IDictionary<String, int> batch) { if (batch.ContainsKey("9")) { reset.Set(); } }; Converter<int, String> keyResolver = x => x.ToString(); counter.SubscribeToKeyedBatch<int, String>(fiber, cb, keyResolver, 0); for (var i = 0; i < 10; i++) { counter.Publish(i); } Assert.IsTrue(reset.WaitOne(10000, false)); } }
public void Batching() { using (var fiber = new ThreadFiber()) { fiber.Start(); var counter = new Channel<int>(); var reset = new ManualResetEvent(false); var total = 0; Action<IList<int>> cb = delegate(IList<int> batch) { total += batch.Count; if (total == 10) { reset.Set(); } }; counter.SubscribeToBatch(fiber, cb, 1); for (var i = 0; i < 10; i++) { counter.Publish(i); } Assert.IsTrue(reset.WaitOne(10000, false)); } }
public void DoDemonstration() { // Two instances of the calculator are created. One is named "Odd" // (it calculates the 1st, 3rd, 5th... values in the sequence) the // other is named "Even". They message each other back and forth // with the latest two values and successively build the sequence. var limit = 1000; // Two channels for communication. Naming convention is inbound. var oddChannel = new Channel<IntPair>(); var evenChannel = new Channel<IntPair>(); using (ThreadFiber oddFiber = new ThreadFiber(), evenFiber = new ThreadFiber()) { oddFiber.Start(); var oddCalculator = new FibonacciCalculator(oddFiber, "Odd", oddChannel, evenChannel, limit); evenFiber.Start(); new FibonacciCalculator(evenFiber, "Even", evenChannel, oddChannel, limit); oddCalculator.Begin(new IntPair(0, 1)); oddFiber.Join(); evenFiber.Join(); } }
public void PointToPointPerfTestWithInt() { var executor = new BoundedQueue(new PerfExecutor()) { MaxDepth = 10000, MaxEnqueueWaitTimeInMs = 1000 }; using (var fiber = new ThreadFiber(executor)) { fiber.Start(); var channel = new Channel<int>(); const int max = 5000000; var reset = new AutoResetEvent(false); Action<int> onMsg = delegate(int count) { if (count == max) { reset.Set(); } }; channel.Subscribe(fiber, onMsg); using (new PerfTimer(max)) { for (var i = 0; i <= max; i++) { channel.Publish(i); } Assert.IsTrue(reset.WaitOne(30000, false)); } } }
public void AsyncStop() { ThreadFiber threadFiber = new ThreadFiber(new CommandQueue()); threadFiber.Start(); threadFiber.Enqueue(threadFiber.Dispose); threadFiber.Join(); }
public FibonacciCalculator(ThreadFiber fiber, string name, ISubscriber<IntPair> inboundChannel, IChannel<IntPair> outboundChannel, int limit) { _threadFiber = fiber; _name = name; _inboundChannel = inboundChannel; _outboundChannel = outboundChannel; _inboundChannel.Subscribe(fiber, CalculateNext); _limit = limit; }
public void PubSubWithDedicatedThread() { using (var fiber = new ThreadFiber()) { fiber.Start(); var channel = new Channel<string>(); var reset = new AutoResetEvent(false); channel.Subscribe(fiber, delegate { reset.Set(); }); channel.Publish("hello"); Assert.IsTrue(reset.WaitOne(5000, false)); } }
private static void Run(long n, bool useSameThread) { AutoResetEvent done1 = new AutoResetEvent(false), done2 = new AutoResetEvent(false); IQueue q1 = new DefaultQueue(), q2 = new DefaultQueue(); IFiber f1 = new ThreadFiber(q1), f2 = useSameThread ? f1 : new ThreadFiber(q2); IChannel<long> c1 = new Channel<long>(), c2 = new Channel<long>(); c2.Subscribe(f2, (x) => { if (x < n) { c1.Publish(++x); } if (x >= n) { done2.Set(); } } ); c1.Subscribe(f1, (x) => { if (x < n) { c2.Publish(++x); } if (x >= n) { done1.Set(); } } ); f1.Start(); if (!useSameThread) f2.Start(); c1.Publish(0); EventWaitHandle.WaitAll(new[] { done1, done2 }); f1.Dispose(); f2.Dispose(); }
public void AsyncRequestReplyWithPrivateChannelUsingThreads() { IFiber responder = new ThreadFiber(); responder.Start(); IFiber receiver = new ThreadFiber(); receiver.Start(); Channel<Channel<string>> requestChannel = new Channel<Channel<string>>(); Channel<string> replyChannel = new Channel<string>(); AutoResetEvent reset = new AutoResetEvent(false); Action<Channel<string>> onRequest = delegate(Channel<string> reply) { reply.Publish("hello"); }; requestChannel.Subscribe(responder, onRequest); Action<string> onMsg = delegate(string msg) { Assert.AreEqual("hello", msg); reset.Set(); }; replyChannel.Subscribe(receiver, onMsg); Assert.IsTrue(requestChannel.Publish(replyChannel)); Assert.IsTrue(reset.WaitOne(10000, false)); responder.Dispose(); receiver.Dispose(); }
public void DoDemonstration() { // We create a source to generate the quadratics. var sinkFiber = new ThreadFiber("sink"); // We create and store a reference to 10 solvers, // one for each possible square term being published. var quadraticChannels = new IChannel<Quadratic>[10]; // reference-preservation list to prevent GC'ing of solvers var solvers = new List<QuadraticSolver>(); var solvedChannel = new Channel<SolvedQuadratic>(); for (var i = 0; i < quadraticChannels.Length; i++) { var fiber = new ThreadFiber("solver " + (i + 1)); fiber.Start(); quadraticChannels[i] = new Channel<Quadratic>(); solvers.Add(new QuadraticSolver(fiber, quadraticChannels[i], solvedChannel)); } var source = new QuadraticSource(quadraticChannels, quadraticChannels.Length, DateTime.Now.Millisecond); // Finally a sink to output our results. sinkFiber.Start(); new SolvedQuadraticSink(sinkFiber, solvedChannel, quadraticChannels.Length); // This starts streaming the equations. source.PublishQuadratics(); // We pause here to allow all the problems to be solved. sinkFiber.Join(); Console.WriteLine("Demonstration complete."); }
private static void RunBoundedQueue() { var executor = new BoundedQueue(new PerfExecutor()) { MaxDepth = 10000, MaxEnqueueWaitTimeInMs = 1000 }; using (var fiber = new ThreadFiber(executor)) { fiber.Start(); var channel = new Channel<MessageStruct>(); const int max = 5000000; var reset = new AutoResetEvent(false); Action<MessageStruct> onMessage = delegate(MessageStruct count) { if (count.count == max) { reset.Set(); } }; channel.Subscribe(fiber, onMessage); using (new PerfTimer(max)) { for (var i = 0; i <= max; i++) { channel.Publish(new MessageStruct { count = i }); } Assert.IsTrue(reset.WaitOne(30000, false)); } } }
public void PubSubWithDedicatedThreadWithFilter() { using (var fiber = new ThreadFiber()) { fiber.Start(); var channel = new Channel<int>(); var reset = new AutoResetEvent(false); Action<int> onMessage = x => { Assert.IsTrue(x % 2 == 0); if (x == 4) { reset.Set(); } }; var sub = new Receiver<int>(fiber, onMessage); sub.Filter = x => x % 2 == 0; channel.Subscribe(sub); channel.Publish(1); channel.Publish(2); channel.Publish(3); channel.Publish(4); Assert.IsTrue(reset.WaitOne(5000, false)); } }
protected override void SetUp() { _fiber = new ThreadFiber(); _fiber.Start(); }
public void ShouldIncreaseThreadFiberSubscriberCountByOne() { var fiber = new ThreadFiber(); fiber.Start(); var channel = new Channel<int>(); Assert.AreEqual(0, fiber.SubscriptionsCount); Assert.AreEqual(0, channel.SubscribersCount); channel.Subscribe(fiber, x => { }); Assert.AreEqual(1, fiber.SubscriptionsCount); Assert.AreEqual(1, channel.SubscribersCount); fiber.Dispose(); Assert.AreEqual(0, fiber.SubscriptionsCount); Assert.AreEqual(0, channel.SubscribersCount); }
private static void Execute(Func<ThreadFiber> creator, String name) { Console.WriteLine(name); const int channelCount = 5; var msPerTick = 1000.0/Stopwatch.Frequency; var channels = new Channel<Message>[channelCount]; for (var i = 0; i < channels.Length; i++) { channels[i] = new Channel<Message>(); } var fibers = new ThreadFiber[channelCount]; for (var i = 0; i < fibers.Length; i++) { fibers[i] = creator(); fibers[i].Start(); var prior = i - 1; var isLast = i + 1 == fibers.Length; var target = !isLast ? channels[i] : null; if (prior >= 0) { Action<Message> cb = delegate(Message message) { if (target != null) { target.Publish(message); } else { var now = Stopwatch.GetTimestamp(); var diff = now - message.Time; if (message.Log) { Console.WriteLine("qTime: " + diff * msPerTick); } message.Latch.Set(); } }; channels[prior].Subscribe(fibers[i], cb); } } for (var i = 0; i < 10000; i++) { var s = new Message(false); channels[0].Publish(s); s.Latch.WaitOne(); } for (var i = 0; i < 5; i++) { var s = new Message(true); channels[0].Publish(s); Thread.Sleep(10); } foreach (var fiber in fibers) { fiber.Dispose(); } }
private static void RunBusyWaitQueue() { var executor = new BusyWaitQueue(new PerfExecutor(), 100000, 30000); using (var fiber = new ThreadFiber(executor)) { fiber.Start(); var channel = new Channel<MsgStruct>(); const int max = 5000000; var reset = new AutoResetEvent(false); Action<MsgStruct> onMsg = delegate(MsgStruct count) { if (count.count == max) { reset.Set(); } }; channel.Subscribe(fiber, onMsg); using (new PerfTimer(max)) { for (var i = 0; i <= max; i++) { channel.Publish(new MsgStruct { count = i }); } Assert.IsTrue(reset.WaitOne(30000, false)); } } }
public void PointToPointPerfTestWithObject() { var executor = new BoundedQueue(new PerfExecutor()) { MaxDepth = 100000, MaxEnqueueWaitTimeInMs = 1000 }; using (var fiber = new ThreadFiber(executor)) { fiber.Start(); var channel = new Channel<object>(); const int max = 5000000; var reset = new AutoResetEvent(false); var end = new object(); Action<object> onMessage = delegate(object message) { if (message == end) { reset.Set(); } }; channel.Subscribe(fiber, onMessage); using (new PerfTimer(max)) { var message = new object(); for (var i = 0; i <= max; i++) { channel.Publish(message); } channel.Publish(end); Assert.IsTrue(reset.WaitOne(30000, false)); } } }