Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3212312
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T14:49:32+00:00 2026-05-17T14:49:32+00:00

I have a WPF application that kicks off 3 threads and needs to wait

  • 0

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.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T14:49:32+00:00Added an answer on May 17, 2026 at 2:49 pm

    Assuming you can use .NET 4, I’m going to show you how to do this in a much cleaner way that avoids sharing mutable state across threads (and thus, avoids locking).

    class PointCloud
    {
        public Point3DCollection Points { get; private set; }
    
        public event EventHandler AllThreadsCompleted;
    
        public PointCloud()
        {
            this.Points = new Point3DCollection(1000);
    
            var task1 = Task.Factory.StartNew(() => AddPoints(0, 0, 192));
            var task2 = Task.Factory.StartNew(() => AddPoints(1, 193, 384));
            var task3 = Task.Factory.StartNew(() => AddPoints(2, 385, 576));
            Task.Factory.ContinueWhenAll(
                new[] { task1, task2, task3 }, 
                OnAllTasksCompleted, // Call this method when all tasks finish.
                CancellationToken.None, 
                TaskContinuationOptions.None,
                TaskScheduler.FromCurrentSynchronizationContext()); // Finish on UI thread.
        }
    
        private void OnAllTasksCompleted(Task<List<Point3D>>[] completedTasks)
        {
            // Now that we've got our points, add them to our collection.
            foreach (var task in completedTasks)
            {
                task.Result.ForEach(point => this.points.Add(point));
            }
    
            // Raise the AllThreadsCompleted event.
            if (AllThreadsCompleted != null)
            {
                AllThreadsCompleted(this, EventArgs.Empty);
            }
        }
    
        private List<Point3D> AddPoints(int scanNum, int x, int y)
        {
           const int goodValue = 42;
           var result = new List<Point3D>(500);
           var points = from pointX in Enumerable.Range(0, x)
                        from pointY in Enumerable.Range(0, y)
                        let pointZ = FindZ(pointX, pointY)
                        where pointZ == goodValue
                        select new Point3D(pointX, pointX, pointZ);
           result.AddRange(points);
           return result;
        }
    }
    

    Consumption of this class is easy:

    // On main WPF UI thread:
    var cloud = new PointCloud();
    cloud.AllThreadsCompleted += (sender, e) => MessageBox.Show("all threads done! There are " + cloud.Points.Count.ToString() + " points!");
    

    Explanation of this technique

    Think about threading differently: instead of trying to synchronize thread access to shared data (e.g. your point list), instead do heavy lifting on the background thread but don’t mutate any shared state (e.g. don’t add anything to the points list). For us, this means looping over X and Y and finding Z, but not adding them to the points list in the background thread. Once we’ve created the data, let the UI thread know we’re done and let him take care of adding the points to the list.

    This technique has the advantage of not sharing any mutable state — only 1 thread accesses the points collection. It also has the advantage of not requiring any locks or explicit synchronization.

    It has another important characteristic: your UI thread won’t block. This is generally a good thing, you don’t want your app to appear frozen. If blocking the UI thread is a requirement, we’d have to rework this solution a bit.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a WPF application that runs fine under XP as an administrator. When
I have written a WPF application that I want to port to Silverlight 2.
I have a simple message box in a WPF application that is launched as
I have a WPF application that runs as a service and renders 2D graphical
We have a WPF application that we've deployed to the customer. However, the application
I have a WPF application that mostly follows MVVM, which I am trying to
hey, i've got a wpf application that have a doubleanimation used for scrolling text
I have a WPF application with a form that, when started, invokes a custom
I have a WPF application in VS 2008 with some web service references. For
I have a WPF application using Aero Glass. When using the application under a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.