2017-04-16 1 views
-1

Jungs. Wie kann ich Daten von List in einer anderen Datei abrufen? Ich versuche, auf diese Weise, aber es ist nicht funktionieren:C# Listenvariable

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 
} 

In einer anderen Datei:

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

Könnten Sie genauer auf was "Es funktioniert nicht" bedeutet? - Ich vermute, dass Sie eine NULL-Referenzausnahme erhalten, weil 'LoadCharacterData' nicht' Characters' initialisiert hat (beachten Sie, dass es sich um eine asynchrone Methode handelt). In diesem Fall haben Sie dann Zugriff auf ein in einer anderen Datei definiertes Feld. Übrigens ist 'List ' nicht Thread-sicher. – Theraot

+0

Ja, Entschuldigung. Ich hatte einen Fehler: System.NullReferenceException: Die Objektreferenz zeigt nicht auf eine Instanz des Objekts. Sie haben Recht. Vielleicht beraten Sie, wie man am besten remake? – Joseph

Antwort

1

In diesem speziellen Fall, das Problem ist, dass Sie brauchen, um einige bedeutet, den Zugriff auf die List<Character> Characters zu synchronisieren.

Beachten Sie die Signatur der Methode LoadCharacterData:

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

Es ist ein async Methode. Es wird nicht synchron laufen. Das heißt, wenn Sie CharacterController.LoadCharacterData(player); anrufen, müssen Sie warten, bis es fertig ist.

Sie können dies erreichen, indem Sie den Anrufer async anrufen und await verwenden. Obwohl, ich vermute, dass Sie die Signatur von OnPlayerDownloaded nicht ändern können. In diesem Fall würde nehme ich die retunred Task und warten auf sie:

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

Hinweis: auf Ihrem Code, müssen Sie eine Warnung auf der folgenden Zeile bekommen:

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

Hier , Sie verwenden nicht die Eigenschaft. Sie erstellen eine lokale Variable mit demselben Namen.


Jetzt gibt es eine weitere versteckte Problem ... List<Character> ist nicht Thread-sicher. Betrachten Sie das Problem, das es verursachen würde, wenn Sie zwei Aufrufe an LoadCharacterData zur gleichen Zeit ausgeführt hätten! - List<Character> ist nicht dafür ausgelegt.

Ich schlage vor, LoadCharacterData neu zu schreiben Task<List<Characater>> zurückzukehren und haben es die List<Character> zurückkehren, anstatt sie an die Öffentlichkeit Eigenschaft schreiben:

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

Alternativ könnte man bedenkt, Zugriff auf das Eigentum zu synchronisieren oder faul Initialisierung verwenden ... aber beachte, dass List<Character> nichts über die Client sagt. Ich weiß nicht, ob es mehrere Anrufe zu LoadCharacterData mit verschiedenen Client geben kann, die sich gegenseitig überarbeiten können.

+0

Danke. Ich werde Ihre Erfahrung nutzen und Ihrem Rat folgen.Ich habe es schon gemacht und alles funktioniert) Ich hoffe, dass ich später keine Probleme damit haben werde. Danke noch einmal. – Joseph

Verwandte Themen