c# – 多线程,lambdas和局部变量

前端之家收集整理的这篇文章主要介绍了c# – 多线程,lambdas和局部变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的问题是,在下面的代码中,我可以确定实例方法将访问我认为它们将要的变量,还是可以在我还在工作时由另一个线程更改?封闭是否与此有关,即我将处理IEnumerable< T>的本地副本了.所以枚举是安全的吗?

为了解释我的问题,如果我从不写共享变量,是否需要任何锁定?

  1. public class CustomerClass
  2. {
  3. private Config cfg = (Config)ConfigurationManager.GetSection("Customer");
  4.  
  5. public void Run()
  6. {
  7. var serviceGroups = this.cfg.ServiceDeskGroups.Select(n => n.Group).ToList();
  8.  
  9. var groupedData = DataReader.GetSourceData().AsEnumerable().GroupBy(n => n.Field<int>("ID"));
  10. Parallel.ForEach<IGrouping<int,DataRow>,CustomerDataContext>(
  11. groupedData,() => new CustomerDataContext(),(g,_,ctx) =>
  12. {
  13. var inter = this.FindOrCreateInteraction(ctx,g.Key);
  14.  
  15. inter.ID = g.Key;
  16. inter.Title = g.First().Field<string>("Title");
  17.  
  18. this.CalculateSomeProperty(ref inter,serviceGroups);
  19.  
  20. return ctx;
  21. },ctx => ctx.SubmitAllChanges());
  22. }
  23.  
  24. private Interaction FindOrCreateInteraction(CustomerDataContext ctx,int ID)
  25. {
  26. var inter = ctx.Interactions.Where(n => n.Id = ID).SingleOrDefault();
  27.  
  28. if (inter == null)
  29. {
  30. inter = new Interaction();
  31. ctx.InsertOnSubmit(inter);
  32. }
  33.  
  34. return inter;
  35. }
  36.  
  37. private void CalculateSomeProperty(ref Interaction inter,IEnumerable<string> serviceDeskGroups)
  38. {
  39. // Reads from the List<T> class instance variable. Changes the state of the ref'd object.
  40. if (serviceGroups.Contains(inter.Group))
  41. {
  42. inter.Ours = true;
  43. }
  44. }
  45. }

解决方法

我似乎找到了答案,在这个过程中,也是问题.

真正的问题是,对于并发访问,本地“变量”(实际上是对象)是否可以信任.答案是否定的,如果它们恰好具有未以线程安全方式处理的内部状态,则所有投注均已关闭.闭包没有帮助,它只是捕获对所述对象的引用.

在我的具体情况中 – 来自IEnumerable< T>的并发读取.并且没有写入它,它实际上是线程安全的,因为每次调用foreach,Contains(),Where()等都会获得一个全新的IEnumerator,它只能从请求它的线程中看到.但是,还必须逐个检查任何其他对象.

所以,万岁,没有锁或同步的集合给我:)

感谢@ebb和@Dave,虽然你没有直接回答这个问题,但你指出了我正确的方向.

如果您对结果感兴趣,可以使用Thread.SpinWait在家用PC(四核)上运行,以模拟一行的处理时间.在本地网络上使用sql Server的双核超线程机器上,真正的应用程序几乎提高了2倍(01:03 vs 00:34).

单线程,使用foreach.我不知道为什么,但是有相当多的跨核心上下文切换.

使用Parallel.ForEach,在需要的地方使用线程本地锁定.

猜你在找的C#相关文章