Project DescriptionThe Joins project provides asynchronous concurrency semantics based on join calculus and modeled after the Microsoft Research Cω (C Omega) project.
AsynchronousThis library provides a simple API for executing logic asynchronously through the Async class:
Async.Invoke(2, 3, (x, y) => {
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
});
Action<int, int> AddAsync = Async.Create<int, int>((x, y) => {
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
});
AddAsync(2, 3);
SynchronizationThis library also provides a join API similar to that of chords in Cω. You create Signal instances which are similar to async methods without bodies. You then create Join instances which can block until a signal or group of signals are invoked releasing the thread and executing a provided delegate.
Signal<int> signal = Signal.Create<int>();
Join join = Join.Create();
Action<int> action = Async.Create<int>(x => {
Thread.Sleep(5000);
Console.WriteLine("Sending {0}", x);
signal.Invoke(x);
});
action(10);
Console.WriteLine("Waiting...");
join.Yield(signal, x => {
Console.WriteLine("Received {0}", x);
});
Console.WriteLine("Finished");
SampleThe following demonstrates a very simple blocking queue that permits only a single item to be inserted. Attempting to get a value from the queue when it has no item will block, as will attempting to add a value when it already has a value.
public class BlockingQueue<T> {
private readonly Signal<T> itemAdded = Signal.Create<T>();
private readonly Signal empty = Signal.Create();
private readonly Join addItemJoin = Join.Create();
private readonly Join getItemJoin = Join.Create();
public BlockingQueue() {
empty.Invoke();
}
public void AddItem(T item) {
addItemJoin.Yield(empty, () => {
itemAdded.Invoke(item);
});
}
public T GetItem() {
return getItemJoin.Yield(itemAdded, item => {
empty.Invoke();
return item;
});
}
}