2017-04-16 5 views
-1

人。 リストから別のファイルでデータを取得するにはどうすればよいですか?私はこの方法を試したが、それが動作しないのです。C#変数のリスト

CharacterController.cs

public class CharacterController 
{ 
public static List<Character> Characters { get; set; } 

public static async Task LoadCharacterData(Client player) 
{ 
    var filter = new BsonDocument("NameOfTable", player.Name); 
    var characters = await DatabaseManager.Characters.Find(filter).ToListAsync(); 

    List<Character> Characters = new List<Character>(); 
    foreach (var character in characters) 
    { 
    Characters.Add(new Character 
     { 
     Name = character.Name, 
     Surname = character.Surname 
     } 
    ); 
    } 

    Console.WriteLine("TEST: " + Characters[0].Name + Characters[0].Surname); //It's working 
} 

を別のファイルではこの特定のケースで

public void OnPlayerDownloaded(Client player) 
{ 
    CharacterController.LoadCharacterData(player); 
    Console.WriteLine("TEST: " + CharacterController.Characters[0].Name + CharacterController.Characters[0].Surname); // It's don't working 
} 
+0

"それは働かない"とはどういう意味ですか? 'LoadCharacterData'が' Characters'を初期化していないので(非同期メソッドであることに注意してください)、null参照例外が発生している可能性があります。その場合、別のファイルで定義されたフィールドにアクセスすることに成功しています。ところで、 'List 'はスレッドセーフではありません。 – Theraot

+0

よろしくお願いいたします。私はエラーがありました: System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスを指していません。 あなたはそうです。 あなたはリメイクするのに最善の方法をアドバイスしますか? – Joseph

答えて

1

、問題は、あなたが持っている必要があるということですList<Character> Charactersへのアクセスを同期する手段があります。

お知らせ方法LoadCharacterDataのシグネチャは:

public static async Task LoadCharacterData(Client player) 
{ 
    // ... 
} 

非同期方法です。それは同期的に実行されません。つまり、CharacterController.LoadCharacterData(player);に電話すると、それが完了するまで待つ必要があります。

これは、発信者をasyncにしてawaitを使用することで実現できます。しかし、あなたはOnPlayerDownloadedの署名を変更することはできません。その場合、私はretunred Taskを取り、それを待つだろう:

public void OnPlayerDownloaded(Client player) 
{ 
    var task = CharacterController.LoadCharacterData(player); 
    task.Wait(); // <--- 
    Console.WriteLine("TEST: " + CharacterController.Characters[0].Name + CharacterController.Characters[0].Surname); 
} 

注:ここでは

List<Character> Characters = new List<Character>(); 

:あなたのコードに、次の行に警告を取得する必要がありますあなたはその物件を使用していません。同じ名前のローカル変数を作成しています。今


、別の隠された問題はList<Character>はスレッドセーフではありません...そこにあります。同じ時刻にLoadCharacterDataが2回呼び出された場合に発生する問題を考えてみましょう。 - List<Character>はそれを処理するように設計されていません。

私はTask<List<Characater>>を返し、それが公共の財産に書き込むのではなく、List<Character>を返すようにLoadCharacterDataを書き換えることをお勧め:

public static async Task<List<Character>> LoadCharacterData(Client player) 
{ 
    var filter = new BsonDocument("NameOfTable", player.Name); 
    var characters = await DatabaseManager.Characters.Find(filter).ToListAsync(); 

    List<Character> result = new List<Character>(); 
    foreach (var character in characters) 
    { 
    result.Add(new Character 
     { 
     Name = character.Name, 
     Surname = character.Surname 
     } 
    ); 
    } 
    return result; 
} 

また、あなたはプロパティへのアクセスを同期するか、遅延初期化を使用することを検討することもでき... List<Character>にはClientについては何も言及していません。私はLoadCharacterDataと複数の通話があり、お互いの仕事を無効にする可能性があるかどうかは分かりません。Client

+0

ありがとうございます。私はあなたの経験を活用し、あなたの助言に従います。私はすでにそれをやって、すべてが動作します)私は後でそれに何か問題がないことを願っています。再度、感謝します。 – Joseph

関連する問題