用于增量线程参与者执行的C#静态公共字段

时间:2018-12-01 17:46:10

标签: c# multithreading static thread-safety akka.net

我正在使用AKKA.net构建一个系统(可能与该问题无关),并且我有一个班级负责统计正在运行的演员人数(对于谁不知道演员的人,他们可能看起来像是线程)简化)。所以基本上我有一个静态的公共领域:

class MyClass{
    public static long TotalOutstandingRequests;
}

并且我在actor / threads中增加/减少它(因为我有actores开始/运行其他actores),

Interlocked.Increment(ref MyClass.TotalOutstandingRequests);
Interlocked.Decrement(ref MyClass.TotalOutstandingRequests);

发生的事情是IDE和Internet认为拥有一个公共静态字段是一个坏主意,所以我想知道我的问题是否有替代方案,或者是否完全可以是的。

2 个答案:

答案 0 :(得分:1)

如果使用得当,这并不是一个坏主意。

无论如何,您可以公开一些静态方法,例如:

public static long AddRequest() 
{
    return Interlocked.Increment (ref _totalOutstandingRequests);
}

public static long RemoveRequest() 
{
    return Interlocked.Decrement (ref _totalOutstandingRequests);
}

public static long GetRequests() 
{
    return _totalOutstandingRequests;
}

答案 1 :(得分:1)

一个坏主意是因为它可能会变成非静态的超时(在您开发时)。

为什么问?仅仅因为在某个时间点,您将需要在此静态对象中使用非静态依赖。无论是记录器,数据库,助手类,服务,连接,还是其他具有不同生命周期的东西。

另一方面,通过使用非静态,您可以通过确保一次创建轻松地将其变为静态,或使用依赖项注入轻松管理单个和其他可能的生命周期(是的,存在多个生存期,例如每个连接,每个会话,每个线程等)。

至于解决方案:

public class MyClass
{
    public long TotalOutstandingRequests;
    private readonly ILogger _logger;
    //some incrementing, decrementing code here
    public MyClass(ILogger logger)
    {
        _logger = logger;
    }
    public void AddRequest()
    {
        Interlocked.Increment(ref TotalOutstandingRequests);
        _logger.Debug("New request here!");
    }
}

那么什么时候使用静态?简单:

  • 当您确定它没有依赖项时,将来也将不再存在,并会陷入僵局(语言扩展,例如LINQ,Regex,任何辅助方法,常量等)
  • 您正在使用非托管代码(调用Windows函数等)。

我从没见过代码,除了这两种情况,没有静态代码就无法生存。

PS

如果它是家庭项目-您可以忘记我说的话,然后按照自己想要的方式进行操作=)