0

次のコードを検討してください。

    private static void Main(string[] args)
    {
        var person = new Person { Manager = new Manager { Name = "Shahrooz" }, Name = "Sina" };
        Console.WriteLine("I am {0} my manager is {1}", person.Name, person.Manager.Name);
        //Outpu:I am Sina my manager is Shahrooz
        var newManager = person.Manager;
        person.Manager = null;

        new Thread(() => File.WriteAllText( Path.Combine("C:\\", string.Format("{0}.txt", person.Name)), new JavaScriptSerializer().Serialize(person))).Start();
        Console.WriteLine("I am {0} my manager is", person.Name);
        person.Manager = newManager;
        Console.ReadLine();
    }
}

public class Person
{
    public string Name { get; set; }
    public Manager Manager { get; set; }
}

public class Manager
{
    public string Name { get; set; }
}

でオブジェクトをシリアライズしようとしていますJavaScriptSerializer。シリアル化する前に、人のマネージャーを null に設定しましたが、テキスト ファイルで素晴らしい結果が得られます。

{"Name":"Sina","Manager":{"Name":"Shahrooz"}}

混同しました。私を助けてください。

アップデート:

私は自分のコードを変更します.それは大丈夫です:

  internal class Program
    {
        private static  void Main(string[] args)
        {
            var person = new Person { Manager = new Manager { Name = "Shahrooz" }, Name = "Sina" };
            Console.WriteLine("I am {0} my manager is {1}", person.Name, person.Manager.Name);
            //Outpu:I am Sina my manager is Shahrooz
            var x = person.Manager;
            person.Manager = null;
            add(person);
            Console.WriteLine("I am {0} my manager is", person.Name);
            person.Manager = x;
            Console.ReadLine();
        }

        public static async void add(Person person)
        {
            await AddToFile(person);

        }

        private async static Task AddToFile(Person person)
        {
            File.WriteAllText(Path.Combine("C:\\", string.Format("{0}.txt", person.Name)), new JavaScriptSerializer().Serialize(person));
        }
    }

    public class Person
    {
        public string Name { get; set; }
        public Manager Manager { get; set; }
    }

    public class Manager
    {
        public string Name { get; set; }
    }
4

2 に答える 2

6

問題は、オブジェクトをシリアル化するために作成したスレッドがメイン スレッドと競合することです。メイン スレッドが Manager 参照をリセットする前にオブジェクトをシリアル化する場合もあれば、後でオブジェクトをシリアル化する場合もあります。

いくつかのソリューションのアイデアを次に示します。

  • スレッドを完全に削除します。この縮小された例では、役に立ちません。元のコードでは、おそらくそうではありません。
  • オブジェクトへのアクセスを同期します。つまり、なんらかの形式の同期を使用して、メイン スレッドで続行する前に、スレッドがシリアル化を完了していることを確認します。もちろん、メイン スレッドがワーカーを開始した直後にその完了を待機する場合は、そもそもスレッドを使用する意味がないため、同期をよりきめ細かく行う必要があります。
  • 処理するオブジェクトのプライベート コピーをスレッドに渡します。つまり、既存の Person を変更する代わりに、Manager が null であることを除いてすべて同じプロパティを持つ新しい Person を作成し、それをスレッドに渡します。
于 2013-07-11T11:08:40.943 に答える
0

あなたのマネージャーは newManager への同じ参照を持っており、実際にはマネージャーは null ではないためです。

于 2013-07-11T11:08:04.393 に答える