简体   繁体   English

Parallel.ForEach中的C#错误

[英]C# error in Parallel.ForEach

I have a strange problem that I am unable to debug. 我有一个奇怪的问题,我无法调试。 Here's a delegate that parses information: 这是解析信息的委托:

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 ();
            }
        };

The delegate itself is called twice, as follows: 委托本身被两次调用,如下所示:

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");
            }
        );

Everything appears to run correctly. 一切似乎都能正常运行。 In particular, the Parallel.ForEach portion of the delegate runs without any error. 特别是,委托的Parallel.ForEach部分运行时没有任何错误。 But then the code breaks at the line Ctx.SaveChanges (), with the message "Object reference not set to an instance of an object." 但是随后代码在Ctx.SaveChanges()行处中断,并显示消息“对象引用未设置为对象的实例”。 But when I hover over Ctx (in this broken state), Ctx is not shown to be null. 但是,当我将鼠标悬停在Ctx​​上(处于此损坏状态)时,Ctx不会显示为空。

Can someone please tell me what is going on? 有人可以告诉我发生了什么吗? Thanks in advance. 提前致谢。

认为应该是:

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

Okay, after much scanning through MSDN documentation, I appear to have come up with at least one solution for now. 好的,在仔细阅读了MSDN文档之后,我看来目前至少已经提出了一种解决方案。 Here is the re-factored code. 这是重构后的代码。

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");
            }
        );

I had to use a different overloaded signature of Parallel.ForEach. 我必须使用Parallel.ForEach的其他重载签名。 In this overload, the equivalent to the Ctx variable in the previous example ("v" in this example, please pardon the cryptic variable names) is not shared. 在此重载中,不共享与上一个示例中的Ctx变量等效的示例(在此示例中为“ v”,请原谅隐式变量名称)。 So the error is avoided. 因此避免了错误。

I would still appreciate a comment from someone knowledgeable as to whether my solution is the only one, or whether there is a better, more idiomatic C# solution. 我仍然希望有一位博学的人对我的解决方案是否是唯一的解决方案,或者是否有更好,更惯用的C#解决方案发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM