I am trying to find the best way to dispose the CCR Dispatcher, DispatcherQueue and Interleave which are interlinked to each other. I have a class say "MyClass" that has a single dispatcher and a single dispatcher queue. The class exposes a single PortSet to which clients can post messages to. In "MyClass", I have created persistent receivers for those messages and attached to the dispatcher queue. I have also added all the receivers as part of a single Interleave. Now when the client thinks it is done using "MyClass" class, I want the client to destroy the class safely. There are three things that needs to destroy here which are the dispatcher, the dispatcher queue and the interleave. What is the best way to do that? I happened to read the discussions in the link http://channel9.msdn.com/shows/Going+Deep/CCR-Programming-Jeffrey-Richter-and-George-Chrysanthakopoulos/. Although, not mentioned explicitly, I inferred that the right way to Dispose is that I need to first post a tear down message to the interleave, wait for the interleave to teardown then dispose the dispatcher queue. Now, the dispose code of my class will look like the following.
var teardownInterleave = new TeardownInterleave();
InternalMessagesPort.PostUnknownType(teardownInterleave);
var done = new ManualResetEvent(false);
Activate(Arbiter.Receive(false, teardownInterleave.CompletionPort,
emptyValue => done.Set()));
done.WaitOne();
Thread.Sleep(100);
// Dispose the TaskQ
TaskQueue.Dispose();
/// <summary>
/// Message posted to any interleave asking it to teardown.
/// </summary>
public sealed class TeardownInterleave
{
/// <summary>
/// Gets the completion port.
/// </summary>
/// <value>
/// The completion port.
/// </value>
public Port<EmptyValue> CompletionPort { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="TeardownInterleave" /> class.
/// </summary>
public TeardownInterleave()
{
CompletionPort = new Port<EmptyValue>();
}
}
Please clarify if this is the right approach or am I missing something.
Thanks,
Venkat
Minor Note: On InternalMessagesPort you shouldn't need to use PostUnknownType, you should just be able to use Post()
The only thing that you should need to dispose is the Dispatcher, everything else should take care of itself through garbage collection.
In general CCR objects (ports, tasks, receivers, causalities etc.) work well with GC. In simple terms, as soon as there are no references to a port then everything else that is associated with it will be collected also (assuming no other references of course).
DispatcherQueues are cleaned up when the owning Dispatcher is disposed.