✅ A dictionary that I made isn't working, but only in one method. It works fine elsewhere.

Image 1 is the code for adding the objects to the dictionary public static Dictionary<int, ItemData> Items = new Dictionary<int, ItemData>(); is how I have the dictionary set up and that works just fine. In image 2 when I try to run a task that checks the dictionary with the key 1 it should return the object ItemData with the values 1,"Oak Wood","A simple material for crafting.",0,0 but it returns null and the value for the dictionary is Count = 0 Image 3 is using the same .TryGetValue key in a different method and it's working how it should and returning the right data. I have tried hard coding the ItemData values in the dictionary directly and that didn't change anything so it has to be a problem with the asnyc task is my best guess but google is giving me nothing and I have genuinely no clue where to start doing anything else to fix this.
public class ItemData
{
public int Id;
public string Name;
public string Description;
public int Level;
public int ArmourType;

public ItemData(int Id, string Name, string Description, int Level, int ArmourType)
{
this.Id = Id;
this.Name = Name;
this.Description = Description;
this.Level = Level;
this.ArmourType = ArmourType;
}
}
public class ItemData
{
public int Id;
public string Name;
public string Description;
public int Level;
public int ArmourType;

public ItemData(int Id, string Name, string Description, int Level, int ArmourType)
{
this.Id = Id;
this.Name = Name;
this.Description = Description;
this.Level = Level;
this.ArmourType = ArmourType;
}
}
That's the code for object. This problem only arose when I removed a bool value and added the int ArmourType. Image 4 is the code for the async task causing the problem and the line used to run the task is Task.Run(() => Data.Skill(4, 10000, 1, 1, 3, 10, 15)).Wait(); If anything else is needed to help I can provide it.
No description
No description
No description
No description
101 Replies
sibber
sibber7d ago
Dictionaries arent threadsafe if you want thread safety use ConcurrentDictionary also dont .Wait tasks the whole point of tasks is to not do that why are you using a task?
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I'm just confused because it used to be (int, string, string, int, bool) and worked fine but when I changed the object to (int, string, string, int, int) is when it stopped working. I didn't know how else to do what I needed to do.
sibber
sibber7d ago
what im trying to ask is what are you trying to do
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Oh, it's a video game in the command line and the only way I could figure out how to save the information about the menu you're in while doing Task (in game, not the coding sense) was to make it a seperate thread.
sibber
sibber7d ago
have you learned classes yet?
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yes I think I have more than just that 1 at the very least
sibber
sibber7d ago
oh yeah i just saw the class you have declared lol whats up with me today anyway
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Lol, all good
sibber
sibber7d ago
that (int, string, string, int, bool) thing should probably be class let me check out your codei just switched to my pc actually first of all $paste
MODiX
MODiX7d ago
If your code is too long, you can post to https://paste.mod.gg/, save, and copy the link into chat for others to see your shared code!
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yeah that's what I meant. The class for the ItemData object used to be (int, string, string, int, bool) but I changed it to (int, string, string, int, int) and then the task broke.
sibber
sibber7d ago
so what you have now is a dictionary of ItemData? and when you change ItemData your code breaks?
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
The only thing I haven't tried is changing the ItemData class back to (int, string, string, int, bool)
sibber
sibber7d ago
can you show the code where you add your item to the dict? just to be clear, do you mean by that an actual tuple, or that the ItemData class has those fields
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
public static void DictAdd()
{
ItemData[] items = {
new ItemData(0,"Dummy's Defense","+1,000,000 HP",1000000,1),
new ItemData(1,"Oak Wood","A simple material for crafting.",0,0),
new ItemData(11,"Oak Stick","A simple stick from the first available wood in the game.",0,0),
new ItemData(21,"Stone","A simple material for crafting.",0,0),
new ItemData(36,"Ore 1","The first ore used for crafting simple metal items.",0,0),
new ItemData(61,"Ore 1 Bar","An ingot form of the first ore",0,0)
};
foreach (ItemData item in items)
{
Items.Add(item.Id, item);
}
}
public static void Main()
{
DictAdd();
...
public static void DictAdd()
{
ItemData[] items = {
new ItemData(0,"Dummy's Defense","+1,000,000 HP",1000000,1),
new ItemData(1,"Oak Wood","A simple material for crafting.",0,0),
new ItemData(11,"Oak Stick","A simple stick from the first available wood in the game.",0,0),
new ItemData(21,"Stone","A simple material for crafting.",0,0),
new ItemData(36,"Ore 1","The first ore used for crafting simple metal items.",0,0),
new ItemData(61,"Ore 1 Bar","An ingot form of the first ore",0,0)
};
foreach (ItemData item in items)
{
Items.Add(item.Id, item);
}
}
public static void Main()
{
DictAdd();
...
sibber
sibber7d ago
you could initialize the dict wit those
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
The item class has those fields
sibber
sibber7d ago
also your main isnt async
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
And it does, it just doesn't work in the task The main doesn't call the task
sibber
sibber7d ago
if you have async code your main should be async
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I didn't know that Main does fairly little in my program tho
sibber
sibber7d ago
rule of thumb is await amything async, async all the way up you can just do that for now if all you need is delays until you learn async properly or you can just use Thread.Sleep anyway where is it called then the thing that takes the item from the dict
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
A different method called Tutorial() That's in a different class
sibber
sibber7d ago
is your code on github by any chance
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yes
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
GitHub
GitHub - SammyOwO/CMDRPG: A simple RPG game I'm making in the comma...
A simple RPG game I'm making in the command line. Windows only hence CMDRPG and not UnixRPG lol - SammyOwO/CMDRPG
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
That's already the latest version I pushed when I posted this It's a lot worse than you could ever expect
sibber
sibber7d ago
so in general we prefer that the Program class and Main to only do startup and have the game handled in its own class rather than have all that in Program.cs
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Main only does startup
sibber
sibber7d ago
also functions should only do one thing generally if you have a function thats longer than 20 lines its probably too long lines arent a good mesasure of this, just a rule of thumb
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Program.cs has the stuff that I need the whole program to access like that async task
sibber
sibber7d ago
what is a good measure is asking yourself "is this doing only one thing?"
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I have a method that calls a task and if you follow the line of nested loops and if else and switch case statements it's 21 long
sibber
sibber7d ago
if something requires something else, pass it around
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yeah, but that's why it's a dictionary So it can be accessed where it's needed
sibber
sibber7d ago
just to give you an idea, main should probably just be
Game = new();
Game.Start();
Game = new();
Game.Start();
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I mean I guess I can make main 4 lines of code in my case
sibber
sibber7d ago
dictionaries are for "give me a value for this key" access is a whole other thing
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Well I mean that's all I need
sibber
sibber7d ago
anyway ive gone off on a tangent here
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
All good
sibber
sibber7d ago
where are you using that dict
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
For the Inventory menu and for that asnyc task Menu.Inventory() and Data.Skill() Data.cs also holds the classes for the objects As well as the outline for the save file. SaveFile EnemyData and ItemData
sibber
sibber7d ago
another rule of thumb is one file per class right so i think you should refactor your code first before continuing
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I feel like it'd be dumb to put those 3 in a seperate file tho bc it's only used by the Data class in Data.cs
sibber
sibber7d ago
because debugging this is very hard and the more you go on the harder it will be in the future my guess is its a thread safety issue, but i cant follow your code to make sure
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I mean I would refactor it if I knew any other way to write the code. I wrote everything relating to the inventory method yesterday
sibber
sibber7d ago
start by breaking up methods one method that does one thing let me show you an example what does menuOption.TryGetValue do? get a value from the save data?
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
That just makes it so pressing D1 or NumPad1 return the int 1 or D2 and NumPad2 returns 2 etc That's literally just to make menu options work properly whether you use the num pad or the number row It also includes X and I X to quit and I for inventory
sibber
sibber7d ago
right so that for example should be handled by an Input class or something like that because its not related to menus
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Honestly It works I'm just gonna leave it
sibber
sibber7d ago
but its messy and it makes debugging hard this is a good opportunity to learn refactoring you have a bug thats hard to diagnose
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I mean I know what refactoring means and why it's important
sibber
sibber7d ago
thats your motivation
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
But I genuinely can't write my code any other way
sibber
sibber7d ago
im explaining to you right now ^
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yeah, but I wouldn't know how to do that I know how to do that with dictionaries And it would take a solid 10 hours to change
sibber
sibber7d ago
what i meant is move that code there thats how you learn another example,
Console.WriteLine("1. Village (Lvl 0-5) \n2. Caves (Lvl 5-15) \n3. Mines (Lvl 15-25) \n4. Mountains (Lvl 25-40) \n \n0. Go back | I: Inventory \n");
Console.WriteLine("1. Village (Lvl 0-5) \n2. Caves (Lvl 5-15) \n3. Mines (Lvl 15-25) \n4. Mountains (Lvl 25-40) \n \n0. Go back | I: Inventory \n");
this shouldnt just be a random string, there should be a list of places that you display
var place = Console.ReadKey(true);
if (!menuOption.TryGetValue(place.Key, out var option))
{
Console.Clear();
Console.WriteLine($"{place.Key} is not a valid key, try again.");
continue;
}
var place = Console.ReadKey(true);
if (!menuOption.TryGetValue(place.Key, out var option))
{
Console.Clear();
Console.WriteLine($"{place.Key} is not a valid key, try again.");
continue;
}
this would be handled by your Input class e.g. Input.GetKey()
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
What
sibber
sibber7d ago
and the Places function should be named something like GoToPlace and passed the place
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
That's the way it every menu is I didn't even write that code I just copied and pasted it bc it worked
sibber
sibber7d ago
where did you get it from? yeah no dont do that you can copy paste code that works only if you fully understand what it does and why it works
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I mean it's before literally every single menu option in this program
sibber
sibber7d ago
and if youre new you shouldnt even do that, you should write it yourself yeah and im telling you how you should refactor that
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yeah, I understand Basically anything outside of the tutorial function does nothing right now except the inventory
sibber
sibber7d ago
an example of a method that does more than 1 thing, Menu.Places(). it does 1. display places that the user can go to 2. read and process input 3. go to said place these should be 3 different methods
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I don't know how I could break it up
sibber
sibber7d ago
start by refactoring everything that has to do with your bug put those 3 things into their own methods
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
It's just the task method And I can't find anything wrong Nothing about it changed I only changed the ItemData class to have an int at the end rather than a bool
sibber
sibber7d ago
what i meant is, everything from Main to wherever your bug is
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Yeah I couldn't find any issues with any of it It just broke
sibber
sibber7d ago
thats most probably just a coincidince i know, im recommending you refactor that so that you could find the issue
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I tried hard coding the values directly into the dictionary and teh same thing happened in the task
sibber
sibber7d ago
alright those are your options
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
So it's not a problem with putting the values in the dictionary
sibber
sibber7d ago
1. refactor your code, make it easier to debug and more readable, then fix your issue 2. try to figure out whats going on using the debugger 3. try guessing what the issue is and changing random things until it works
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I know where the problem starts. I just have 0 clue why it happens like
sibber
sibber7d ago
^
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I used the debugger to the best of my ability and I tried everything I could think of that related to the code
sibber
sibber7d ago
so that leaves you with option 1
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
The problem there is The only thing that needs ot be refactored is the async task And I don't even know how to re write that
sibber
sibber7d ago
no, far from that like i said, break up methods into things that only do one thing
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Everything else works though
sibber
sibber7d ago
youre asking the same questions in a cycle it works until it doesnt which is now if you want to make it easier, or even possible, to debug
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
The only things that don't work are stuff I didn't write
sibber
sibber7d ago
then you need to refactor
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
besides that menu thing That works rlly well But I didn't write the async task
sibber
sibber7d ago
rewrite them yourself then :)
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I have no clue where to even start I would just rewrite the exact same thing
sibber
sibber7d ago
do that then because youll understand it this time delete the code and write it yourself
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I mean I understand it But that's because I used it I don't understand why it broke though
sibber
sibber7d ago
listen thats all the advice i can give you i already told you why its important to write the code yoruself
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
Oh my god I found the problem
sibber
sibber7d ago
ah so you went with option 4
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
It was from when I refactored my code
sibber
sibber7d ago
look at the code until you randomly find the bug
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I had 2 seperate Items dictionaries And one just isn't being used at all How do I mark solved ?
sibber
sibber7d ago
i hope you take my advice and refactor $close
MODiX
MODiX7d ago
If you have no further questions, please use /close to mark the forum thread as answered
CODGhostsIsGood
CODGhostsIsGoodOP7d ago
I would love to, but I can't.
sibber
sibber7d ago
sure you can

Did you find this page helpful?