Threadsafety和foreach with static readonly array

时间:2016-11-24 02:10:04

标签: c# foreach static thread-safety readonly

我有几个char []和string []类型的数组,它们被定义为' static readonly'。他们的物品永远不变。

' foreach'和'泛型'枚举线程安全?

private static readonly string[] staticReadOnlyArray = new string[] { "someKey0", "someKey1", "someKey2", ... };

public bool SomeThreadSharedCall(string toCheck)
{
    // #1
    foreach (string s in staticReadOnlyArray)
    {
        if (s == toCheck)
            return true;
    }
    return false;

    // #2
    return staticReadOnlyArray.Contains(toCheck);

    // or #3
    return staticReadOnlyArray.Any(s => string.Compare(toCheck, s, StringComparison.OrdinalIgnoreCase) == 0);

    // or #4
    staticReadOnlyArray.ForEach(s => someAction(s, toCheck));
}

2 个答案:

答案 0 :(得分:0)

最好的方法,如果你不确定,就是测试它!但是,是的,它们是线程安全的。

答案 1 :(得分:0)

您方法中的操作是"线程安全"仅基于您Their items never change.的声明;但是,给定代码中没有任何内容可以保证。

术语threadsafe通常用于表示有问题的代码保证数据不会更改,或者如果 可以更改,操作仍会产生正确的结果。

您需要执行your own synchronization logic才能使代码真正具有线程安全性。

===回答你的意见:

GetEnumerator()的返回值 - 您正在调用的iterator - 本身对于调用线程的独占使用是安全的,但这不是问题所在。它是不是线程安全的底层集合(数组),因为它可以改变。

foreach更改为for循环并不会使代码更加安全。您需要同步对集合的访问权限,或使其不可变。

在你的情况下,我建议后者给出数组中的数据是常量。为了使它具体化,这里有一些概念性代码:

private static readonly IEnumerable<string> staticReadOnlyData = Array.AsReadOnly( new string[] { "someKey0", "someKey1", "someKey2", ... } );

public bool SomeThreadSharedCall(string toCheck)
{
    // #1
    foreach (string s in staticReadOnlyData)
    {
        if (s == toCheck)
            return true;
    }
    return false;

    // #2
    return staticReadOnlyData.Contains(toCheck);

    // or #3
    return staticReadOnlyData.Any(s => string.Compare(toCheck, s, StringComparison.OrdinalIgnoreCase) == 0);
}