2017-04-16 45 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'(注意它是一个异步方法)。在这种情况下,您可以成功访问另一个文件中定义的字段。顺便说一句,'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的电话会造成的问题! - List<Character>不适用于处理该问题。

我建议重写LoadCharacterData返回Task<List<Characater>>,并使其返回的List<Character>,而不是将其写入公共财产:

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