C# 如何重构此IEnumerable<;T>;为了线程安全?

C# 如何重构此IEnumerable<;T>;为了线程安全?,c#,thread-safety,C#,Thread Safety,我正在查看Skeet的原子枚举,但我不确定如何将其集成到我当前的IEnumerable exmaple中,如下() 基本上,我想用线程安全的方式来处理我的blahs类型 谢谢 所以。。多线程上的foreach。。。下正确的命令 Blahs b=新的Blahs() foreach(b中的字符串s) {} 公共密封类Blahs:IEnumerable { 私有只读IList_data=new List(){“blah1”、“blah2”、“blah3”}; 公共IEnumerator GetEnum

我正在查看Skeet的原子枚举,但我不确定如何将其集成到我当前的IEnumerable exmaple中,如下()

基本上,我想用线程安全的方式来处理我的blahs类型

谢谢

所以。。多线程上的foreach。。。下正确的命令

Blahs b=新的Blahs()

foreach(b中的字符串s) {}

公共密封类Blahs:IEnumerable
{
私有只读IList_data=new List(){“blah1”、“blah2”、“blah3”};
公共IEnumerator GetEnumerator()
{
返回_data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}

您的意思是希望每个线程看到相同的序列,还是希望在所有线程之间,每个项目只显示一次

你能使用.NET4吗?如果是这样的话,并行扩展(例如,
Parallel.ForEach
)就是你的朋友——它可能比我能想到的任何东西都安全:)


编辑:如果您只想在每个线程中完全迭代列表,并且没有任何东西会修改列表,那么它已经是线程安全的了。如果您确实需要修改列表,那么您应该创建列表的副本,并对其进行迭代。

您的意思是希望每个线程看到相同的序列,还是希望在所有线程之间,每个项目只显示一次

你能使用.NET4吗?如果是这样的话,并行扩展(例如,
Parallel.ForEach
)就是你的朋友——它可能比我能想到的任何东西都安全:)


编辑:如果您只想在每个线程中完全迭代列表,并且没有任何东西会修改列表,那么它已经是线程安全的了。如果确实需要修改列表,则应创建列表的副本并进行迭代。

如果只需要每个线程查看相同的序列,则代码可能是线程安全的

您的
\u数据
列表是私有的,因此只能从
Blahs
类本身中修改它(假设您不在其他地方公开它)

该类对于多个并发读卡器是安全的,这意味着您需要做的就是确保您的
Blahs
类在枚举集合时不会修改该集合


您的示例代码实际上是线程安全的,但我相信您真正的代码实际上并不是这么简单。

如果您只需要每个线程看到相同的序列,那么您的代码可能是线程安全的

您的
\u数据
列表是私有的,因此只能从
Blahs
类本身中修改它(假设您不在其他地方公开它)

该类对于多个并发读卡器是安全的,这意味着您需要做的就是确保您的
Blahs
类在枚举集合时不会修改该集合


您的示例代码是线程安全的,但我相信您真正的代码实际上并没有这么简单。

链接的代码解决了另一个问题,您正在尝试做一些更困难的事情。只要集合在被迭代时没有被修改,就不必对迭代器做任何特殊的处理。要保证这一点可能很困难,您必须保持一个锁,以防止任何线程添加项。对于并发性来说不是很好


如果这不合适,那么你必须制作一份收藏品副本以提供担保。也没有玫瑰床,根据定义,线程现在总是会看到旧版本的集合。

链接的代码解决了另一个问题,您正在尝试做更困难的事情。只要集合在被迭代时没有被修改,就不必对迭代器做任何特殊的处理。要保证这一点可能很困难,您必须保持一个锁,以防止任何线程添加项。对于并发性来说不是很好


如果这不合适,那么你必须制作一份收藏品副本以提供担保。也没有玫瑰床,根据定义,一根线现在总是会看到旧版的集合。

我需要每条线看到相同的序列。不幸的是,我暂时停留在3.5上,我需要每个线程看到相同的序列。不幸的是,我暂时还停留在3.5上
public sealed class Blahs :  IEnumerable<string>
{
    private readonly IList<string> _data = new List<string>() { "blah1", "blah2", "blah3" };

    public IEnumerator<string> GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}