0

デバッグできない奇妙な問題があります。情報を解析するデリゲートは次のとおりです。

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

デリゲート自体は、次のように 2 回呼び出されます。

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は表示されませんnull

誰かが何が起こっているのか教えてもらえますか?

4

2 に答える 2

0

次のように考えてください。

ParallelEnumerable.Range (0, Records.Count()-1)
于 2011-03-31T07:56:29.240 に答える
0

さて、MSDN のドキュメントを精査した結果、今のところ少なくとも 1 つの解決策を思いついたようです。これがリファクタリングされたコードです。

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# ソリューションがあるのか​​について、知識のある人からのコメントをいただければ幸いです。

于 2011-03-31T09:03:28.763 に答える