为了解释我的问题,如果我从不写共享变量,是否需要任何锁定?
public class CustomerClass{ private Config cfg = (Config)ConfigurationManager.GetSection("Customer"); public voID Run() { var serviceGroups = this.cfg.ServiceDeskGroups.Select(n => n.Group).ToList(); var groupedData = DataReader.GetSourceData().AsEnumerable().GroupBy(n => n.FIEld<int>("ID")); Parallel.ForEach<IGrouPing<int,DaTarow>,CustomerDataContext>( groupedData,() => new CustomerDataContext(),(g,_,ctx) => { var inter = this.FindOrCreateInteraction(ctx,g.Key); inter.ID = g.Key; inter.Title = g.First().FIEld<string>("Title"); this.CalculateSomeProperty(ref inter,serviceGroups); return ctx; },ctx => ctx.submitAllChanges()); } private Interaction FindOrCreateInteraction(CustomerDataContext ctx,int ID) { var inter = ctx.Interactions.Where(n => n.ID = ID).SingleOrDefault(); if (inter == null) { inter = new Interaction(); ctx.InsertOnsubmit(inter); } return inter; } private voID CalculateSomeProperty(ref Interaction inter,IEnumerable<string> serviceDeskGroups) { // Reads from the List<T> class instance variable. Changes the state of the ref'd object. if (serviceGroups.Contains(inter.Group)) { inter.Ours = true; } }}解决方法 我似乎找到了答案,在这个过程中,也是问题.
真正的问题是,对于并发访问,本地“变量”(实际上是对象)是否可以信任.答案是否定的,如果它们恰好具有未以线程安全方式处理的内部状态,则所有投注均已关闭.闭包没有帮助,它只是捕获对所述对象的引用.
在我的具体情况中 – 来自IEnumerable< T>的并发读取.并且没有写入它,它实际上是线程安全的,因为每次调用foreach,Contains(),Where()等都会获得一个全新的IEnumerator,它只能从请求它的线程中看到.但是,还必须逐个检查任何其他对象.
所以,万岁,没有锁或同步的集合给我:)
感谢@ebb和@Dave,虽然你没有直接回答这个问题,但你指出了我正确的方向.
如果您对结果感兴趣,可以使用Thread.SpinWait在家用PC(四核)上运行,以模拟一行的处理时间.在本地网络上使用sql Server的双核超线程机器上,真正的应用程序几乎提高了2倍(01:03 vs 00:34).
单线程,使用foreach.我不知道为什么,但是有相当多的跨核心上下文切换.
使用Parallel.ForEach,在需要的地方使用线程本地锁定.
总结以上是内存溢出为你收集整理的c# – 多线程,lambdas和局部变量全部内容,希望文章能够帮你解决c# – 多线程,lambdas和局部变量所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)