如何在使用多线程时添加到列表?

jho*_*ton 7 c# multithreading web-services list .net-3.5

我是多线程的新手,过去只玩过它.但我很好奇是否有可能在主线程上有一个字节数组列表,并且仍然可以在单独的线程中创建新的字节数组时添加到该列表.此外,我将使用for-each循环,它将遍历将用于解析为字节数组的表单列表.所以基本上伪代码就像这样......

reports = new List();

foreach (form in forms)  
{  
    newReport = new Thread(ParseForm(form));  
    reports.Add(newReport);  

}  

void ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}
Run Code Online (Sandbox Code Playgroud)

希望上面的伪代码有一定意义.如果有人能告诉我这是否可能并指出我的方向,我相信我可以找出实际的代码.

Ale*_*ore 5

在我们意识到它是 .Net 3.5 之前,请保留 .Net 4 的参考

如果列表中不需要任何顺序,一个简单的“修复”方法是使用ConcurrentBag<T>类而不是列表。如果您需要更多订单,还有一个ConcurrentQueue<T>集合。

如果您确实需要更自定义的东西,您可以使用 BlockingCollection<T> 实现您自己的阻塞集合。 这是一篇关于该主题的好文章

您还可以使用 Parallel.Foreach 来避免显式创建线程:

private void ParseForms()
{
    var reports = new ConcurrentBag<byte[]>();
    Parallel.ForEach(forms, (form) =>
                                {
                                    reports.Add(ParseForm(form));
                                });

}

private byte[] ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}
Run Code Online (Sandbox Code Playgroud)


das*_*ght 4

如果需要从多个线程访问集合,则应该使用同步,或者SynchronizedCollection如果您的 .NET 版本为 3.0 或更高版本,则应使用 a。

这是使您的线程可以访问该集合的一种方法:

SynchronizedCollection reports = new SynchronizedCollection();

foreach (form in forms) {  
    var reportThread = new Thread(() => ParseForm(form, reports));
    reportThread.Start();
}

void ParseForm(Form form, SynchronizedCollection reports) {  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    reports.Add(newArray);
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 .NET 4 或更高版本,则命名空间的各种类提供了手动管理线程的更好替代方法System.Threading.Tasks。在决定线程实现之前,请考虑探索这种替代方案。