I have a WPF application that kicks off 3 threads and needs to wait for them to finish. I have read many posts here that deal with this but none seem to address the situation where the thread code calls Dispatcher.Invoke or Dispatcher.BeginInvoke. If I use the thread's Join() method or a ManualResetEvent, the thread blocks on the Invoke call. Here's a simplified code snippet of an ugly solution that seems to work:
class PointCloud
{
private Point3DCollection points = new Point3DCollection(1000);
private volatile bool[] tDone = { false, false, false };
private static readonly object _locker = new object();
public ModelVisual3D BuildPointCloud()
{
...
Thread t1 = new Thread(() => AddPoints(0, 0, 192));
Thread t2 = new Thread(() => AddPoints(1, 193, 384));
Thread t3 = new Thread(() => AddPoints(2, 385, 576));
t1.Start();
t2.Start();
t3.Start();
while (!tDone[0] || !tDone[1] || !tDone[2])
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
Thread.Sleep(1);
}
...
}
private void AddPoints(int scanNum, int x, int y)
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
z = FindZ(x, y);
if (z == GOOD_VALUE)
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,
(ThreadStart)delegate()
{
Point3D newPoint = new Point3D(x, y, z);
lock (_locker)
{
points.Add(newPoint);
}
}
);
}
}
}
tDone[scanNum] = true;
}
}
from the main WPF thread...
PointCloud pc = new PointCloud();
ModelVisual3D = pc.BuildPointCloud();
...
Any ideas about how to improve this code would be much appreciated. It seems like this should be a very common problem, but I can't seem to find it properly addressed anywhere.