c# TPL:在外部作用域实例上调用方法

本文关键字:实例 调用 方法 作用域 外部 TPL | 更新日期: 2023-09-27 18:11:40

所以我的标题相当模糊,这就是我担心的。我可以在块外声明的类的实例上调用方法而不会遇到缺陷吗

如下结构的代码是否存在并发问题

HeavyLifter hl = new HeavyLifter();
var someActionBlock = new ActionBlock<string>(n =>
{
   int liftedStuff= hl.DoSomeHeavyLifting(n);
   if (liftedStuff> 0)
   .....
});

我的担忧来源如下。

  1. Block可以同时运行多个线程,每个线程都可以进入DoSomeHeavyLifting方法。是否每个函数调用得到自己的帧指针?我应该确保我没有引用CountWords作用域之外的任何变量吗?

  2. 是否有更好的方法来做到这一点,而不是实例化一个heavy - lifter在我的块?

任何帮助都是非常感谢的,我不太迷路,但我知道并发是潜在错误和角落案例之王。

c# TPL:在外部作用域实例上调用方法

  1. 假设通过帧指针,您指的是堆栈帧,那么是的,每个调用获得它自己的堆栈帧和相关变量。如果函数的形参是引用类型,那么所有的形参都指向同一个对象。对于所有调用使用相同的HeavyLifter实例是否安全取决于DoSomeHeavyLifting方法是否有副作用。即DoSomeHeavyLifting是否修改了HeavyLifter对象状态的任何内容。(或任何其他引用对象)

最终这样做是否安全很大程度上取决于DoSomeHeavyLifting内部做了什么。如果它是为了可重入而精心构造的,那么按照你的方式调用它是没有问题的。然而,如果DoSomeHeavyLifting修改了状态,或者状态被修改为任何其他操作的副作用,那么必须在整个体系结构的上下文中决定如何处理它。例如,您是否允许状态更改并强制原子性,或者您是否阻止任何影响操作的状态更改?如果不知道这个方法实际在做什么,就不可能给出任何具体的建议。

一般来说,当设计并发性时,最好做最坏的打算:
    如果竞态条件可能发生,它就会发生。
  • 当竞态条件发生时,你将以代码允许的最复杂的方式失去竞争。
  • 非原子状态更新会相互破坏,并使你的对象处于未定义状态。
  • 如果你使用锁,就会出现死锁的情况。
  • 在调试时不会发生的事情,在发布时总会发生。