在c#中调用静态是否像我的示例中那样安全?

时间:2015-11-11 23:03:56

标签: c#

我已经在utils.cs类中添加了几个简单的辅助方法。一个例子如下。我从一个asp.net控制器调用它,这意味着可能会在同一时间内在许多线程上发生许多调用。

我意识到我这样做是因为resharper建议让类中的方法保持静态,但我担心这可能是错误的事情,也许我应该在每次调用时新建一下Utils类。

思考?

public class Utils
    {
        public static List<Speaker> FilterSpeakersByTenant(List<Speaker> inSpeakers, string tenantName)
        {
            return
                inSpeakers.
                    Where(speaker => speaker.Sessions.
                        Any(a => a.TenantName == tenantName)).
                    ToList();
        }

5 个答案:

答案 0 :(得分:3)

如果你没有在静态方法中访问全局/共享状态,那么它应该没问题......

当您在并发线程中访问参数(例如列表)时,可能会出现唯一的多线程问题。

如果类没有任何状态(即成员变量或属性),则无论是实例化类还是使用静态方法都没有区别。

答案 1 :(得分:1)

很好。非静态类可以从接口继承。你似乎不需要这里。非静态类可用于创建具有多个状态的多个对象。你也不需要那样。

答案 2 :(得分:1)

Resharper建议您将其设置为静态方法,因为它不访问任何实例成员。由于您不访问任何静态数据,因此您也可以避免多线程问题。

只要您不添加该方法将使用的任何静态或非静态字段,使其static没有任何缺点。

答案 3 :(得分:0)

该方法完全是线程安全的。它没有使用任何共享状态,也没有修改参数。

为了更好的可读性,请考虑将您的方法更改为IEnumerable<Speaker>上的扩展方法:

public static IEnumerable<Speaker> ByTenant(this IEnumerable<Speaker> source, string tenantName)
    {
        return source
               .Where(speaker => speaker.Sessions.Any(a => a.TenantName == tenantName));
    }

然后你可以用它作为

var filteredSpeakers = speakers.ByTenant(tenantName).ToList();

答案 4 :(得分:0)

安全是如此被高估的概念,不是吗? :)。 问题是,它不是一个线程安全的方法,因为输入数据:

List<Speaker> inSpeakers

可以在LINQ Where运算符枚举的同时更改,它会抛出异常,否则会出现竞争条件。

如果您确定,该方法只获取原始列表的副本,那么确定,但我在这里看不到这样的保证。列表用于添加/删除项目并访问它们。

处理线程安全的其他方法是锁定,这在高争用情况下会产生性能副作用。

阵列好一点,项目数量无法改变。

非常好的主意是ImmutableList。

如果你正在寻找在多个线程之间共享状态的方法,那么一些并发的collletction将是最好的情况。