public List<Order.RootObject> DoStuff ()
{
List<Order.RootObject> cOrders = new List<Order.RootObject>();
var client = new RestClient(url);
var request = new RestRequest("orders", Method.GET);
request.AddParameter("pgsize", "2000");
request.AddParameter("pgnum", "1");
var response = client.Execute<Order.RootObject>(request);
int iLoop = response.Data.TotalResults / 2000 + 1;
Parallel.For(1, iLoop,
index => {
request.Parameters[“pgnum”].Value = index;
response = response = client.Execute<Order.RootObject>(request);
cOrders.Add(response.Data);
});
return cOrders;
}cOrders最终不会返回所有的响应。如果我将它改为一个简单的For循环,一切都很好,但它需要很长时间,因为对于某些调用,需要返回到API的许多循环才能获得所需的所有数据。
发布于 2017-09-29 23:04:13
您在循环中重用了请求对象。这是行不通的,因为多个线程将访问和修改这个实例。你必须同步/锁定对请求实例的访问(然后你有一个没有并行化的普通for循环),或者为循环中的每个请求创建一个自己的请求对象……
发布于 2017-09-29 23:19:38
List不是线程安全的。框架中的大多数类型都不是。当在多线程上下文中使用一个类型时,请确保使用check the docs。
此类型的
公共静态(在Visual Basic中为Shared)成员是线程安全的。不能保证任何实例成员都是线程安全的。在一个列表上执行多个读取操作是安全的,但是如果在读取集合时对其进行修改,则可能会出现问题。若要确保线程安全,请在读取或写入操作期间锁定集合。若要使集合能够由多个线程访问以进行读写,您必须实现自己的同步。有关内置同步的集合,请参见System.Collections.Concurrent命名空间中的类。有关固有的线程安全替代方案,请参见ImmutableList类。
我真的很喜欢不可变的集合,在大多数情况下,我更喜欢它们而不是并发集合。不幸的是,对于新用户来说,它们更难使用和理解。任何变化都会产生一个新的集合,然后您必须使用该集合来替换旧版本。这本身并不是类型安全的,但它们附带了一个工具,可以为您处理所有这些问题。
var foo = ImmutableList<string>.Empty;
ImmutableInterlocked.Update(ref foo, list => list.Add("woot"));list.Add("woot")返回一个基于foo的新列表,ImmutableInterlocked.Update将尝试更新foo,直到它确定集合引用已正确更新。您可以用重做工作(list.Add("woot"))代替锁定。
https://stackoverflow.com/questions/46491597
复制相似问题