C
C#2y ago
Waffen

❔ Problem with Dictionary<ulong, Image> (Strange work of memory access)

Concept of my system: A system that draws a picture with stickers, each of the stickers can be moved, there can be an unlimited number of stickers. Code with explanations in comments:
private static Dictionary<ulong, Image> UserStickerProfiles = new();

public static async Task MoveSticker(Sticker sticker)
{
var stickerImage = await ItemManager.GetProfileItemImageAsync(itemId); // take image of sticker from file

UserStickerProfiles.TryGetValue(args.User.Id, out var image);
if (image == null)
{
image = await ProfileMethods.DrawProfileExceptStickerAsync(args.User, itemId); // draw picture without this sticker
UserStickerProfiles.Add(args.User.Id, image);
}

image.Mutate(x => x.DrawImage(stickerImage, new Point(sticker.PositionX, sticker.PositionY), 1f)); // draw this sticker with new coordinations

// saving and sending
var memoryStream = new MemoryStream();
await image.SaveAsPngAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);

// send image to user with memortStream
}
private static Dictionary<ulong, Image> UserStickerProfiles = new();

public static async Task MoveSticker(Sticker sticker)
{
var stickerImage = await ItemManager.GetProfileItemImageAsync(itemId); // take image of sticker from file

UserStickerProfiles.TryGetValue(args.User.Id, out var image);
if (image == null)
{
image = await ProfileMethods.DrawProfileExceptStickerAsync(args.User, itemId); // draw picture without this sticker
UserStickerProfiles.Add(args.User.Id, image);
}

image.Mutate(x => x.DrawImage(stickerImage, new Point(sticker.PositionX, sticker.PositionY), 1f)); // draw this sticker with new coordinations

// saving and sending
var memoryStream = new MemoryStream();
await image.SaveAsPngAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);

// send image to user with memortStream
}
Problem: Each time you use this function, a new picture should appear with ALL stickers and the sticker that we moved to a new location. However, it happens that the sticker is duplicated and there are several of them. The suggestion line image.Mutate(x => x.DrawImage(stickerImage, new Point(sticker.PositionX, sticker.PositionY), 1f)); updates the Dictionary directly, though it shouldn't be, presumably because C# has a memory bug here. I am using .NET 7.0
7 Replies
Sherbert Lemon
where do itemId and args come from?
Kouhai
Kouhai2y ago
updates the Dictionary directly, though it shouldn't be Do you mean it shouldn't update the instance of image saved in the Dictionary? You're only doing this operation if image == null, so the dictionary isn't effected
Waffen
WaffenOP2y ago
Take it like a constant Yes, i know that dictionary isn't effected and it's can't be updated but it is
Sossenbinder
Sossenbinder2y ago
That looks a lot like imagesharp, and as far as I can remember, imagesharp works in-place, so it will mutate the existing Image reference If you want to make a copy of what you have instead of mutating it in-place, you should be able to use the .Clone(...) method That will return a cloned image which won't affect the original reference
Kouhai
Kouhai2y ago
How does DrawProfileExceptStickerAsync work?
Waffen
WaffenOP2y ago
@Sossenbinder Thank you very much! It works!
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server