【问题标题】:How do Threads work in Objects线程如何在对象中工作
【发布时间】:2009-06-18 06:50:23
【问题描述】:

大家好,我在线程方面完全没有经验,所以这是我的问题:

线程如何在对象的实例中工作,特别是,我正在处理 Windows 服务

那么,我的服务基本上是一个对象的实例,对吧?

假设我的服务中有一个 System.Timers.Timer,它每 10 秒触发一次 ElapsedEventHandler。

假设 Timer 事件处理程序中的每个操作需要 1 分钟才能完成。

每个事件是否由不同的线程处理?

如果是这样,我的对象的属性对此有何反应?属性是否跨线程共享?

线程限制是多少?他们用完了吗?如果是这样,当 Timer Event 触发并且所有线程都被占用时会发生什么?

非常感谢,我对如何跨线程共享属性特别感兴趣??如果是这样的话。

干杯!

【问题讨论】:

    标签: .net multithreading windows-services


    【解决方案1】:

    Jon Skeet 有一些关于线程基础的介绍性页面,here(请注意这里有 17 个单独的主题页面)。

    每个事件是否由不同的线程处理?

    这取决于具体的计时器,但这是一个安全(即最坏情况)的假设

    属性是否跨线程共享?

    是的;除非您自己编写,否则无法防止多个线程访问您的数据,或者使用[MethodImpl(MethodImplOptions.Synchronized)](使方法同步),或者使用诸如lock之类的构造。唯一的例外是使用特殊属性 [ThreadStatic] 标记的静态字段,然后每个线程都有一个静态字段。

    线程限制是多少?他们用完了吗?如果是这样,当 Timer Event 触发并且所有线程都被占用时会发生什么?

    部分受限于操作系统资源,部分受限于它们是“常规”线程还是池线程。但是,如果您使用的足够多,这会成为一个问题,那么您的线程就太多了。如果没有足够的资源来启动一个线程,要么它会开始失败(常规线程),要么工作会简单地堆积起来,等待更多的可用性(池线程)。完全有可能使线程池饱和并死锁一切。基本上避免过多的线程。

    【讨论】:

      【解决方案2】:

      这是一个相当复杂的话题,我建议在这里花一些时间阅读 msdn 上的大量线程文档:http://msdn.microsoft.com/en-us/library/3e8s7xdd.aspx

      每个计时器经过的事件都在一个单独的线程上处理(这些线程来自控制线程可用性的 ThreadPool)。对象和属性是跨线程共享的,你有责任锁定临界区。我使用静态 Interlocked 类进行轻量级锁定。如果你用谷歌搜索的话,会有很多例子。

      【讨论】:

        【解决方案3】:

        是的,每次触发事件时,都会在线程池线程上进行处理。此外,内存中只有一个对象实例,因此线程将共享对相同变量的访问。

        阅读线程和计时器是一个非常好的主意,也许看看一些例子,因为否则你可能会在让事情可靠地工作的过程中拔掉大部分头发。

        注意:我希望您的处理程序不会在每 10 秒事件触发时花费 1 分钟,因为那样您的运行线程数将每分钟增加 5 个并且永远不会再下降......您不能继续做更多和更多的工作同时进行。

        【讨论】:

        • 哈哈,不,不,10 秒/1 分钟的事情只是为了争论。当前,如果一项任务已经发生,则静态布尔值会阻止处理程序中正在进行的任何工作。我只是想进一步了解它。所以,我假设一旦范围离开那个事件处理程序,那个特定的线程就会被释放,对吗?
        • 如果您要保持这种方式,我建议您跳过计时器并生成您自己的线程,该线程循环并检查是否有任何事情要做,然后在该线程上执行工作,那里没有必要让事情变得更复杂!这会给你1个线程,没有计时器......
        • @andy:事件处理程序完成后,线程返回到线程池......(虽然它不会终止,但对你没有任何实际影响)跨度>
        • @Petoj,使用您的“生成自己的线程”解决方案,您是否建议在每次迭代期间使用 Thread.Sleep?这比计时器更复杂且更容易出错。一方面,定时器更容易清理。
        【解决方案4】:

        System.Timers.Timer 将在每次 Elapsed 触发时使用一个线程池线程,我不知道是否有最大值,但我希望线程池应该以一种好的方式处理这个问题.. 但同时运行到多个线程不推荐,cpu必须一直换线程,这是有代价的。

        属性在不同的线程之间共享,但如果你不让它们线程安全,它们就不是线程安全的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-07-01
          • 2016-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-05
          • 1970-01-01
          相关资源
          最近更新 更多