C# 线程安全并行 public List DoStuff() { 列表记录者=新列表(); var client=新的RestClient(url); var请求=新的重新请求(“订单”,方法.GET); 请求添加参数(“pgsize”、“2000”); 请求.AddParameter(“pgnum”,“1”); var response=client.Execute(请求); int iLoop=response.Data.TotalResults/2000+1; 平行。对于(1,iLoop, 索引=>{ 参数[“pgnum”]。值=索引; response=response=client.Execute(请求); 添加(响应.数据); }); 回线器; }

C# 线程安全并行 public List DoStuff() { 列表记录者=新列表(); var client=新的RestClient(url); var请求=新的重新请求(“订单”,方法.GET); 请求添加参数(“pgsize”、“2000”); 请求.AddParameter(“pgnum”,“1”); var response=client.Execute(请求); int iLoop=response.Data.TotalResults/2000+1; 平行。对于(1,iLoop, 索引=>{ 参数[“pgnum”]。值=索引; response=response=client.Execute(请求); 添加(响应.数据); }); 回线器; },c#,rest-client,parallel.for,C#,Rest Client,Parallel.for,录像机最终不会得到API返回的所有响应。如果我将其更改为简单For循环,则一切都很好,但这需要很长时间,因为对于某些调用,有许多返回到API的循环,以获取我所需的所有数据。您正在循环中重用请求对象。这是行不通的,因为多个线程将访问和修改这个实例。 您必须同步/锁定对“请求”实例的访问(然后您有一个正常的for循环,没有并行化),或者为循环中的每个请求创建一个自己的请求对象…列表不是线程安全的。框架中的大多数类型不是。在多线程上下文中使用时,请确保 此类型的公共静态(在Visual Basic中共

录像机最终不会得到API返回的所有响应。如果我将其更改为简单For循环,则一切都很好,但这需要很长时间,因为对于某些调用,有许多返回到API的循环,以获取我所需的所有数据。

您正在循环中重用请求对象。这是行不通的,因为多个线程将访问和修改这个实例。
您必须同步/锁定对“请求”实例的访问(然后您有一个正常的for循环,没有并行化),或者为循环中的每个请求创建一个自己的请求对象…

列表不是线程安全的。框架中的大多数类型不是。在多线程上下文中使用时,请确保

此类型的公共静态(在Visual Basic中共享)成员是线程安全的。任何实例成员都不能保证线程安全。 对一个列表执行多个读取操作是安全的,但如果在读取集合时对其进行修改,则可能会出现问题。为确保线程安全,请在读或写操作期间锁定集合。要使集合能够由多个线程访问以进行读写,必须实现自己的同步。有关内置同步的集合,请参阅System.collections.Concurrent命名空间中的类。有关固有的线程安全替代方案,请参见ImmutableList类

我真的很喜欢不可变集合,在大多数情况下,我更喜欢它们而不是并发集合。不幸的是,对于较新的用户来说,它们更难使用和理解。任何变异都会产生一个新的集合,然后您必须使用它来替换旧版本。这本身不是类型安全的,但它们附带了一个工具,可以为您解决所有这些问题

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;
    }
var foo=ImmutableList.Empty;
immutableinterlocted.Update(reffoo,list=>list.Add(“woot”);

list.Add(“woot”)
返回基于
foo
的新列表,
ImmutableInterlocated.Update
将尝试更新
foo
,直到它确定集合引用已正确更新。用重做工作(
list.Add(“woot”)
)代替锁定

除了下面在
RestClient
List
上提到的线程安全问题外,您还应该检查服务器将支持多少并发连接,并限制
并行调用中的
MaxDegreeOfParallelism
var foo = ImmutableList<string>.Empty;
ImmutableInterlocked.Update(ref foo, list => list.Add("woot"));