So after a long time of cursing and giving up hope I got everything to work (almost).
I have a GUI which displays a list of connected addresses and a list of messages. Normally when I close a connector (disconnect from an address) I write a message saying: "disconnected from address x". However as you will see from the methods, when disposing the application I cannot use the dispatcher to write that message (this.ModuleConnections.Remove(address);
triggers the writing of the message and also removes it visually from the list).
private void CloseConnector(string address)
{
Task task = new Task(() =>
{
var moduleConnection = this.ModuleConnections[address];
moduleConnection.ModuleConnector.Dispose();
if (mDisposed == true)
{
ApplicationSupport.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(() =>
{
this.ModuleConnections.Remove(address);
}));
}
});
task.Start();
if (mDisposed == true)
{
mTasks.Add(task);
}
}
protected virtual void Dispose(bool disposing)
{
// Dispose managed resources.
if ((mDisposed == false) && (disposing == true))
{
mTasks.Clear();
mDisposed = true;
CloseConnectors();
Task.WaitAll(mTasks.ToArray());
}
}
I cannot use the dispatcher because Task.WaitAll stops the thread. If the thread is stopped the dispatcher cannot execute this.ModuleConnections.Remove(address);
and this results in the task not finishing, if the tasks not finish Task.WaitAll won't release the thread. Which is a very big problem.
Without the task.waitall i would get a tremendous amount of object disposed and key not found exceptions and other nasty things which kept some threads running and thus the application wouldn't shut down completely.
But now, when it closes, the GUI freezes (looks like it crashed) for a few seconds and then (when task.waitall is finished) it closes the window and the entire application is closed correctly.
What I want is to still be able to update my list of messages and display what addresses have disconnected.
Just to clarify
I need the Task in the CloseConnector method because closing the connector (dispose) makes it disconnect, it needs to wait until it receives a message back from the other side before the code continues. if i were to run this 1 by one it would take minutes, in parallel as i do it now it only takes a few seconds.