1

我创建了一个ThreadManager处理类,Threads它的任务是添加新threads的和清理死的threads。但是,threads所创建的仍处于活动状态并处于ThreadState.WaitSleepJoin状态。我已经检查过主体是否已成功完成执行。有任何想法吗?

    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));
    }

在主线程中执行:

    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);
            }
        }
    }
4

2 回答 2

2

当程序的主启动线程终止时,您可以要求 CLR 为您自动中止线程。但这不是自动的,您必须将线程的 IsBackground 属性显式设置为 true。线程池线程会自动打开该属性。

于 2012-07-30T15:27:34.403 回答
1

WaitSleepJoin 表示线程已通过调用 lock (Monitor.Enter)、调用 Thread.Sleep、调用 Thread.Join 或其他一些线程同步对象来阻塞自己。

也许如果您提供导致此线程状态的示例线程入口点,有人可以提供更详细的答案。

于 2012-07-30T15:22:18.230 回答