sha*_*mor 69 c# parallel-processing locking list
我正在尝试运行连接到远程站点(通过网络)的多个功能并返回通用列表.但我想同时运行它们.
例如:
public static List<SearchResult> Search(string title)
{
//Initialize a new temp list to hold all search results
List<SearchResult> results = new List<SearchResult>();
//Loop all providers simultaneously
Parallel.ForEach(Providers, currentProvider =>
{
List<SearchResult> tmpResults = currentProvider.SearchTitle((title));
//Add results from current provider
results.AddRange(tmpResults);
});
//Return all combined results
return results;
}
Run Code Online (Sandbox Code Playgroud)
正如我所看到的,"结果"的多次插入可能同时发生......这可能会导致我的应用程序崩溃.
我怎么能避免这个?
Mar*_*ers 141
您可以使用并发集合.
该
System.Collections.Concurrent命名空间提供了应该发生在相应类型的使用几个线程安全的集合类System.Collections和System.Collections.Generic命名空间,只要多线程并发访问的集合.
例如,您可以使用,ConcurrentBag因为您无法保证将添加项目的顺序.
表示线程安全,无序的对象集合.
Hae*_*ian 51
//In the class scope:
Object lockMe = new Object();
//In the function
lock (lockMe)
{
results.AddRange(tmpResults);
}
Run Code Online (Sandbox Code Playgroud)
基本上,锁意味着只有一个线程可以同时访问该关键部分.
aro*_*eer 23
并发集合是.Net 4的新功能; 它们旨在使用新的并行功能.
在.NET 4之前,如果多个线程可能正在访问单个共享集合,则必须提供自己的同步机制.你必须锁定集合......
... System.Collections.Concurrent中的[new]类和接口[在.NET 4中添加]为涉及跨线程共享数据的多线程编程问题提供了一致的实现.
Mat*_*ius 23
对于喜欢代码的人:
public static ConcurrentBag<SearchResult> Search(string title)
{
var results = new ConcurrentBag<SearchResult>();
Parallel.ForEach(Providers, currentProvider =>
{
results.Add(currentProvider.SearchTitle((title)));
});
return results;
}
Run Code Online (Sandbox Code Playgroud)
Dou*_*las 12
这可以用简洁PLINQ的表达AsParallel和SelectMany:
public static List<SearchResult> Search(string title)
{
return Providers.AsParallel()
.SelectMany(p => p.SearchTitle(title))
.ToList();
}
Run Code Online (Sandbox Code Playgroud)