Parallel.ForEach中的C#错误

时间:2011-03-31 07:49:32

标签: c#

我有一个奇怪的问题,我无法调试。这是一个解析信息的代表:

Action<XElement, String> ParseXMLInfo = (s, t) => {
            using (var Ctx = new Entities ()) {
                var Records = s.Elements ("record");
                Parallel.ForEach (
                    ParallelEnumerable.Range (0, Records.Count ()),
                    u => {
                        var el = Records.ElementAt (u);
                        try {
                            var NTR = new tbl_UserInfo ();
                            NTR.first_name = el.Element ("first_name").Value;
                            NTR.last_name = el.Element ("last_name").Value;
                            Ctx.AddTotbl_UserInfo (NTR);
                        } catch (Exception excp) {
                            Console.WriteLine (System.DateTime.Now + " " + excp.Message);
                        }
                    }
                );
                Ctx.SaveChanges ();
            }
        };

委托本身被调用两次,如下所示:

Parallel.Invoke (
            () => {
                var XMLDoc_MaleInfo = XElement.Load ("MaleNames.xml");
                Console.WriteLine ("Fetching records from MaleNames.xml; starting at " + System.DateTime.Now);
                ParseXMLInfo (XMLDoc_MaleInfo, "male");
            },
            () => {
                var XMLDoc_FemaleInfo = XElement.Load ("FemaleNames.xml");
                Console.WriteLine ("Fetching records from FemaleNames.xml; starting at " + System.DateTime.Now);
                ParseXMLInfo (XMLDoc_MaleInfo, "female");
            }
        );

一切似乎都正常运行。特别是,委托的Parallel.ForEach部分运行时没有任何错误。但是代码在Ctx.SaveChanges()行中断,并显示消息“对象引用未设置为对象的实例”。但是当我将鼠标悬停在Ctx​​上时(处于这种破坏状态),Ctx不显示为空。

有人可以告诉我发生了什么事吗?提前谢谢。

2 个答案:

答案 0 :(得分:0)

认为应该是:

ParallelEnumerable.Range (0, Records.Count()-1)

答案 1 :(得分:0)

好的,经过MSDN文档的大量扫描后,我似乎现在已经提出了至少一个解决方案。这是重新考虑的代码。

Action<XElement, String> ParseXMLInfo = (s, t) => {
            var Records = s.Elements ("record");
            Parallel.ForEach (
                ParallelEnumerable.Range (0, Records.Count ()),
                () => new Testing_And_Benchmarking_Entities (),
                (u, L, v) => {
                    var el = Records.ElementAt (u);
                    var NTR = new tbl_UserInfo ();
                    NTR.first_name = el.Element ("first_name").Value;
                    NTR.last_name = el.Element ("last_name").Value;
                    v.AddTotbl_UserInfo (NTR);
                    return v;
                },
                (v) => v.SaveChanges ()
            );
        };
        Parallel.Invoke (
            () => {
                var XMLDoc_MaleInfo = XElement.Load ("MaleNames.xml");
                Console.WriteLine ("Fetching records from MaleNames.xml; starting at " + System.DateTime.Now);
                ParseXMLInfo (XMLDoc_MaleInfo, "male");
            },
            () => {
                var XMLDoc_FemaleInfo = XElement.Load ("FemaleNames.xml");
                Console.WriteLine ("Fetching records from MaleNames.xml; starting at " + System.DateTime.Now);
                ParseXMLInfo (XMLDoc_FemaleInfo, "female");
            }
        );

我不得不使用Parallel.ForEach的不同重载签名。在这个重载中,相当于前一个例子中的Ctx变量(在这个例子中为“v”,请原谅神秘的变量名称)不是共享的。因此避免了错误。

我仍然感谢知情人士的评论,我的解决方案是否是唯一的,或者是否有更好的,更惯用的C#解决方案。