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

  • SEARCH
  • Home
  • 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 8282183
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T10:17:08+00:00 2026-06-08T10:17:08+00:00

I am having a kinda annoying problem mostly due to my low skill level/experience

  • 0

I am having a kinda annoying problem mostly due to my low skill level/experience in C# multithreading.

Here is the background. In my framework, I have a static class named WaitFormHelper, which has two static methods (well… actually more but we don’t care here), Start() and Close()
The Start() method initializes and starts a thread which will acquire a lock on the locker object and create a WaitForm (which is a small loading control with a custom message and a progress bar)

In my current project, I have a method which starts a WaitForm, performs calculations, then closes the WaitForm. Nothing fancy at all.
The method looks like the following, I simplified it as much as possible:

public void PerformCalculations()
{
   try
   {
      WaitFormHelper.Start("Title", "message", false);
      if (this.CalculationsParameters.IsInvalid)
      {
         return;
      }
      // Perform all those lengthy calculations here
   } 
   // catch whatever exception I may have to catch, we don't care here
   finally
   {
      WaitFormHelper.Close();
   }
}

Here are the Start() and Close() methods with related methods & attributes, simplified as well:

private static Thread instanceCaller;
private static WaitForm instance;

private static AutoResetEvent waitFormStarted = new AutoResetEvent(false);
private static object locker = new object();

/// <summary>
/// Initializes WaitForm to start a single task
/// </summary>
/// <param name="header">WaitForm header</param>
/// <param name="message">Message displayed</param>
/// <param name="showProgressBar">True if we want a progress bar, else false</param>
public static void Start(string header, string message, bool showProgressBar)
{
    InitializeCallerThread(showProgressBar, header, message);
    instanceCaller.Start();
}

/// <summary>
/// Initializes caller thread for executing a single command
/// </summary>
/// <param name="showProgressBar"></param>
/// <param name="header"></param>
/// <param name="message"></param>
private static void InitializeCallerThread(bool showProgressBar, string header, string message)
{
    waitFormStarted.Reset();

    instanceCaller = new Thread(() =>
    {
        lock (locker)
        {
            instance = new WaitForm()
            {
                Header = header,
                Message = message,
                IsProgressBarVisible = showProgressBar
            };
            waitFormStarted.Set();
        }
        instance.ShowDialog();
    });
    instanceCaller.Name = "WaitForm thread";
    instanceCaller.SetApartmentState(ApartmentState.STA);
    instanceCaller.IsBackground = true;
}

/// <summary>
/// Closes current form
/// </summary>
public static void Close()
{
    lock (locker)
    {
        if (instance != null && !instance.IsClosed)
        {
            waitFormStarted.WaitOne();
            instance.FinalizeWork();
            instance.Dispatcher.Invoke(
                new Action(() =>
                {
                    instance.Close();
                }));
        }
    }
}

Now let’s get to the problem

This usually works fine, except in this case:
If this.CalculationsParameters.IsInvalid is true (ie. as you probably already understood, I can’t perform calculations for some reason, such as “user entering crap in my forms”), the execution directly closes my WaitForm.
However in this case, the main thread will reach the Close method and acquire a lock on the locker object before the thread fired by the Start() method.

What happens is that: Close acquires lock, tries to close the form but instance is still null because the Thread created in InitializeCallerThread is still waiting for the lock to actually create it. Close releases lock, InitializeCallerThread acquires it and… shows a WaitForm which will not close.

Now I know that I can simply fix this problem by testing if the calculation parameters are invalid before actually starting the WaitForm, but well, problem is this WaitForm is supposed to be used by all applications of our framework (which includes 40+ different apps used and maintained in 4 countries), so ideally I’d rather prefer seeing my WaitForm working at all cases.

Do you have any idea on how could I synchronize this to make sure the starter thread is definitely called and executed first?
As you can see I already use an AutoResetEvent for this matter, but if I listen to it before the test if (instance != null) I will end up stuck in my case.

Hope this is clear enough! Thank you!

  • 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-06-08T10:17:10+00:00Added an answer on June 8, 2026 at 10:17 am

    You need some mechanism to make a “queue control”, coordinating steps according to the order you want them occurring.

    Recently I have needed to implement something like this to force a specific order in the execution of several threads in a unit test.

    Here is my suggestion:

    QueueSynchronizer:

    /// <summary>
    /// Synchronizes steps between threads.
    /// </summary>
    public class QueueSynchronizer
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="minWait">Minimum waiting time until the next try.</param>
        /// <param name="maxWait">Maximum waiting time until the next try.</param>
        public QueueSynchronizer(Int32 minWait, Int32 maxWait)
        {
        }
    
        private Mutex mx = new Mutex();
        /// <summary>
        /// Minimum waiting time until the next try.
        /// </summary>
        private Int32 minWait = 5;
        /// <summary>
        /// Maximum waiting time until the next try.
        /// </summary>
        private Int32 maxWait = 500;
    
        int currentStep = 1;
    
        /// <summary>
        /// Key: order in the queue; Value: Time to wait.
        /// </summary>
        private Dictionary<int, int> waitingTimeForNextMap = new Dictionary<int, int>();
    
        /// <summary>
        /// Synchronizes by the order in the queue. It starts from 1. If is not 
        /// its turn, the thread waits for a moment, after that, it tries again, 
        /// and so on until its turn.
        /// </summary>
        /// <param name="orderInTheQueue">Order in the queue. It starts from 1.</param>
        /// <returns>The <see cref="Mutex"/>The mutex that must be released at the end of turn.
        /// </returns>
        public Mutex Sincronize(int orderInTheQueue)
        {
            do
            {
                //while it is not the turn, the thread will stay in this loop and sleeping for 100, 200, ... 1000 ms
                if (orderInTheQueue != this.currentStep)
                {
                    //The next in queue will be waiting here (other threads).
                    mx.WaitOne();
                    mx.ReleaseMutex();
    
                    //Prevents 100% processing while the current step does not happen
                    if (!waitingTimeForNextMap.ContainsKey(orderInTheQueue))
                    {
                        waitingTimeForNextMap[orderInTheQueue] = this.minWait;
                    }
                    Thread.Sleep(waitingTimeForNextMap[orderInTheQueue]);
                    waitingTimeForNextMap[orderInTheQueue] = Math.Min(waitingTimeForNextMap[orderInTheQueue] * 2, this.maxWait);
                }
            } while (orderInTheQueue != this.currentStep);
    
            mx.WaitOne();
            currentStep++;
            return mx;
        }
    }
    

    Start() and Close() with QueueSynchronizer:

    //synchronizer
    private static QueueSynchronizer queueSynchronizer;
    
    private static Thread instanceCaller;
    private static WaitForm instance;
    
    private static AutoResetEvent waitFormStarted = new AutoResetEvent(false);
    private static object locker = new object();
    
    /// <summary>
    /// Initializes WaitForm to start a single task
    /// </summary>
    /// <param name="header">WaitForm header</param>
    /// <param name="message">Message displayed</param>
    /// <param name="showProgressBar">True if we want a progress bar, else false</param>
    public static void Start(string header, string message, bool showProgressBar)
    {
        queueSynchronizer = new QueueSynchronizer();
        InitializeCallerThread(showProgressBar, header, message);
        instanceCaller.Start();
    }
    
    /// <summary>
    /// Initializes caller thread for executing a single command
    /// </summary>
    /// <param name="showProgressBar"></param>
    /// <param name="header"></param>
    /// <param name="message"></param>
    private static void InitializeCallerThread(bool showProgressBar, string header, string message)
    {
        waitFormStarted.Reset();
    
        instanceCaller = new Thread(() =>
        {
            lock (locker)
            {
                //Queuing to run on first.
                Mutex mx = queueSynchronizer.Sincronize(1);
                try
                {
                    instance = new WaitForm()
                            {
                                Header = header,
                                Message = message,
                                IsProgressBarVisible = showProgressBar
                            };
                }
                finally
                {
                    //I think is here that ends the first step!?
                    mx.ReleaseMutex();
                }
    
                waitFormStarted.Set();
            }
            instance.ShowDialog();
        });
        instanceCaller.Name = "WaitForm thread";
        instanceCaller.SetApartmentState(ApartmentState.STA);
        instanceCaller.IsBackground = true;
    }
    
    /// <summary>
    /// Closes current form
    /// </summary>
    public static void Close()
    {
        //Queuing to run on second.
        Mutex mx = queueSynchronizer.Sincronize(2);
        try
        {
            lock (locker)
            {
                if (instance != null && !instance.IsClosed)
                {
                    waitFormStarted.WaitOne();
                    instance.FinalizeWork();
                    instance.Dispatcher.Invoke(
                        new Action(() =>
                        {
                            instance.Close();
                        }));
                }
            }
        }
        finally
        {
            mx.ReleaseMutex();
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am having a kinda strange problem. Here is the situation. I have a
I am kinda having a strange requirement. I have a google talk bot &
I'm having an annoying problem with my iPhone app. Whenever I set the optimization
Hello guys im having little problem here, Firstly i want to parse string which
So I'm having this strange problem. I have a ribbon moving behind the navigation
I'm currently having a annoying problem with MySQL. I started at a point where
In our e-commerce application, we have different kinds of products having different kinds of
I have a page having certain pictures and i show around 20 pictures, kind
Ok, so I'm having a problem with a simple textarea. I'm using a kind
I have been having this debate with my boss for a long time, now

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.