Question

I have created a ThreadManager class that handles Threads and its task is to add new threads and clean up the dead threads. However, the threads that are created remain alive and in ThreadState.WaitSleepJoin state. I have checked that the body has successfully finished execution. Any ideas?

    public bool TryAddThread(ThreadStart threadBody, ThreadStartInfo startInfo)
    {
        bool success = false;

        // Validate arguments
        if (threadBody == null || startInfo == null)
        {
            return false;
        }

        if (!Monitor.TryEnter(_lock) || !_allowNewThreads)
        {
            return false;
        }

        try
        {
            Thread newThread = new Thread(threadBody);

            StartThread(newThread, null, startInfo);

            success = true;
        }
        finally
        {
            Monitor.Exit(_lock);
        }

        return success;
    }

    private void StartThread(Thread newThread, object threadParams, ThreadStartInfo startInfo)
    {
        if (newThread == null || startInfo == null)
        {
            return;
        }

        // Apply start info
        newThread.Name = startInfo.Name;
        newThread.SetApartmentState(startInfo.ApartmentState);
        newThread.IsBackground = startInfo.IsBackground;

        if (threadParams == null)
        {
            newThread.Start();
        }
        else
        {
            newThread.Start(threadParams);
        }

        _threads.Add(newThread);

        RemoveDeadThreads();
    }

    public void RemoveDeadThreads()
    {
        _threads.RemoveAll(t => (!t.IsAlive));
    }

Execution in main thread:

    public void InsertAsync(AP p, APr pr)
    {
        ParameterizedThreadStart thread = new ParameterizedThreadStart(InsertPr);
        List<object> parameters = new List<object>();

        // Create new controller. Must be before the thread to avoid cross-thread operation exception.
        PageController controller = new PageController();
        controller.Initialize(siteWebBrowser);

        parameters.Add(controller);
        parameters.Add(p);
        parameters.Add(pr);
        parameters.Add(_session);

        // If the thread cannot start notify listeners
        if (!_threadManager.TryAddThread(thread, parameters, new ThreadStartInfo("InsertAsync", ApartmentState.STA, true)) && ThreadCreationFailed != null)
        {
            _logger.Error("InsertAsync: Could not start thread.");
            ThreadCreationFailed();
        }

    }

    private static void InsertPr(object o)
    {
        try
        {
            _logger.Debug("Thread start - InsertPr");

            List<object> parameters = (List<object>)o;
            PageController controller = (PageController)parameters[0];
            AP p = (AP)parameters[1];
            APr pr = (APr)parameters[2];
            Session session = (Session)parameters[3];

            if (patient == null)
            {
                throw new ArgumentException("Null patient.");
            }

            session.WaitForHistorySynchronizationSuspension();

            if (Program.ShouldAbortBackgroundOperations)
            {
                throw new Exception("Aborting..");
            }

            session.DoingSomeJob = true;



            controller.ClearCurrent();

            controller.GoToHomePage(3, true);

            controller.ClickNew();


            controller.SearchForP(p.Id);


            try
            {
                controller.WaitUntilDivExists(Constants.NewPrContainerDivId);
            }
            catch (Exception)
            {
                _logger.Error("InsertAsync: Error while waiting for div '" + Constants.NewPrContainerDivId + "' to appear.");
                throw;
            }

            if (PrInsertionCompleted != null)
            {
                PrInsertionCompleted();
            }
        }
        catch (Exception ex)
        {
            _logger.ErrorException("InsertAsync", ex);

            if (InsertionFailed != null)
            {
                InsertionFailed(Constants.MessageFailed);
            }
        }
    }
Was it helpful?

Solution

WaitSleepJoin means the thread has blocked itself with a call to lock (Monitor.Enter), a call to Thread.Sleep, or a call to Thread.Join, or some other thread synchronization object.

Maybe if you provide example thread entry point that is causing this thread state, someone can provide a more detailed answer.

OTHER TIPS

You can ask the CLR to automatically abort threads for you when the main startup thread of the program terminates. But that's not automatic, you have to explicitly set the thread's IsBackground property to true. Threadpool threads have that property turned on automatically.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top