Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在线程管理类中正确放置锁对象_C#_Multithreading_Locking - Fatal编程技术网

C# 在线程管理类中正确放置锁对象

C# 在线程管理类中正确放置锁对象,c#,multithreading,locking,C#,Multithreading,Locking,我正在尝试创建一个ThreadManager对象,用于处理在应用程序中创建的线程 其全部目的是在关闭主窗体之前终止线程,并且在关闭期间不允许创建新的线程。正如您所看到的,我在整个线程创建代码以及AllowNewThreads内部应用了锁定 我很确定会有2个或更多的新线程在锁上等待,这不是很糟糕,但可能会导致小的延迟。为了获得更好的结果,是否有另一种锁定位置的替代方案,或者可能还有另一种我尚未考虑的策略 public class ThreadManager { #region Fields

我正在尝试创建一个ThreadManager对象,用于处理在应用程序中创建的线程

其全部目的是在关闭主窗体之前终止线程,并且在关闭期间不允许创建新的线程。正如您所看到的,我在整个线程创建代码以及AllowNewThreads内部应用了锁定

我很确定会有2个或更多的新线程在锁上等待,这不是很糟糕,但可能会导致小的延迟。为了获得更好的结果,是否有另一种锁定位置的替代方案,或者可能还有另一种我尚未考虑的策略

public class ThreadManager
{
    #region Fields
    private List<Thread> _threads;
    private static Logger _logger = LogManager.GetCurrentClassLogger();
    private static object _lock;
    private bool _allowNewThreads;
    #endregion

    #region Properties

    public bool AllowNewThreads
    {
        get
        {
            return _allowNewThreads;
        }
        set
        {
            lock (_lock)
            {
                _allowNewThreads = value;
            }
        }
    }

    public int CountAlive
    {
        get
        {
            int count = (from t in _threads where (t.IsAlive) select t).Count();
            return count;
        }
    }
    #endregion

    #region Constructors
    private ThreadManager()
    {
        _threads = new List<Thread>();
    }

    public static ThreadManager Instance
    {
        get { return Singleton<ThreadManager>.Instance; }
    }
    #endregion

    #region Methods

    // There must always be thread body in order to create a new thread.
    // Thread parameters are the objects that are needed for calculations etc inside the thread and are optional
    // Start info is the thread itself parameters needed for its creation, such as the thread name, the apartment state 
    // and if it's background or not. That information is optional as well.
    public bool TryAddThread(ParameterizedThreadStart threadBody, object threadParams, ThreadStartInfo startInfo)
    {
        bool success = true;
        try
        {
            lock (_lock)
            {
                if (!AllowNewThreads)
                {
                    throw new Exception("Creation of new threads is denied.");
                }

                Thread f = new Thread(threadBody);

                if (startInfo != null)
                {
                    f.Name = startInfo.Name;
                    f.SetApartmentState(startInfo.ApartmentState);
                    f.IsBackground = startInfo.IsBackground;
                }

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

                _threads.Add(f);
            }
        }
        catch (Exception ex)
        {
            _logger.ErrorException("AddThread", ex);
            success = false;
        }
        return success;
    }
    #endregion
}

正如您在评论中提到的,您只需要等待线程完成作业。因此,您可以使用ThreadPool来代替手动管理线程,因为它对于短期作业更有效。对于长时间运行的任务,我将使用支持取消的任务类!我认为Rx支持.NET3.5,也许有更简单的方法

线程是非常沉重的对象,它们的管理可能会成为应用程序中一个棘手的部分


在编辑之前,您还应该尝试确保在整个应用程序中,每个类只有一个线程可以锁定的对象,否则会出现严重的错误。

“我正在尝试创建一个线程管理器对象,用于处理在应用程序中创建的线程”。你能找到别的方法做你想做的事吗?队列/线程池/任何不涉及直接线程微管理的东西-痛苦、麻烦、调试困难和麻烦的回报,除非你的老板/客户拿枪指着你的头,否则应该避免,即使这样,我想我还是宁愿被枪毙:。您是否绝对需要终止这些线程,例如,因为它们拥有必须关闭/提交的DB连接/事务?事实上,是的。线程持有数据库连接和事务,必须终止它们。还有一些其他线程与网站保持开放连接。目前应用程序的主要问题是线程终止序列,它偶尔会导致访问冲突异常,而.NET3.5框架未处理这些异常。不,很遗憾不能使用4.0。你应该有一个静态锁。我感兴趣的是如何终止线程,当然不是通过调用Abort?线程是自己终止的。禁止堕胎@oleksii为什么要在非静态类上使用静态锁,即使它是单例类?任务在.NET4和4.5中受支持。我认为ThreadPool不适合我的应用程序。每个线程处理不同的数据。我没有矩阵来做计算。我只是解析一些来自网站的数据,然后将这些数据存储到数据库中。还有一个保持活动的线程。大多数应用程序在整个应用程序生命周期内都会运行,但在关闭应用程序时,我必须等待超时过期并提交任何事务。讨论.NET3.5的任务和选项