C
C#3y ago
mindhardt

Won't this code cause EFCore concurrency exceptions?

public async ValueTask<Tag?> GetTag(string name)
{
if (_cache.TryGetValue(name, out object? cachedTag))
return cachedTag as Tag;

Tag? databaseTag = await _dbctx.Tags.FirstOrDefaultAsync(t => t.Name == name);

if (databaseTag is not null)
_cache.Set(name, databaseTag);

return databaseTag;
}
public async ValueTask<Tag?> GetTag(string name)
{
if (_cache.TryGetValue(name, out object? cachedTag))
return cachedTag as Tag;

Tag? databaseTag = await _dbctx.Tags.FirstOrDefaultAsync(t => t.Name == name);

if (databaseTag is not null)
_cache.Set(name, databaseTag);

return databaseTag;
}
This is the code my bot has, I am unsure if I can do DB calls like this, won't it cause concurrency exceptions? How do I fix it?
27 Replies
mindhardt
mindhardtOP3y ago
This is code for my discord bot, I am afraid that simultaneous calls of this Task will cause Context to do several calls at once, which is not allowed
Nikolaaa
Nikolaaa3y ago
how do you even code a discord bot in c#
mindhardt
mindhardtOP3y ago
...Pretty comfy I must say..?
Nikolaaa
Nikolaaa3y ago
also yea dont try it could get you banned idk the fix i never coded a discord bot in c#
mindhardt
mindhardtOP3y ago
Visit #discord-dev and take a look at $discordlibs
MODiX
MODiX3y ago
Discord.NET (https://github.com/discord-net/Discord.Net) + Relatively easy to use & large & friendly community which makes it easier to get help with the library + Low mantainance for existing bots on library version updates - High memory usage for caching & docs can be a bit lacking (especially for newer features) but overall has a good coverage of the library Disqord (https://github.com/Quahu/Disqord) + Good integration with the .NET generic host + Allows you to modify mostly everything to your heart's content - Heavy reliance on the host builder and DI means you cant use it without the host builder really easily DSharpPlus (https://github.com/DSharpPlus/DSharpPlus) + Beginner friendly + Hides Discord's API to make it easier to use - New functionality takes a while to be added Remora.Discord (https://github.com/Remora/Remora.Discord) + Full flexibility of utilising Discord's API, close to actual implementation + Full integration with .NET IoC, host pipeline - Steeper learning curve, less documentation
Jayy
Jayy3y ago
Why
Nikolaaa
Nikolaaa3y ago
yooo thats lit i may switch my bot to c# anyways i gotta go, i hope you find someone that can help you
Jayy
Jayy3y ago
C# is fine for bots @MODiX is written in c#
Nikolaaa
Nikolaaa3y ago
too many requests?
Jayy
Jayy3y ago
How is that related to c#
mindhardt
mindhardtOP3y ago
The question is about how to access EFCore from different threads
Jayy
Jayy3y ago
You need a different context The code u posted doesn't really say anything tho It's very normal ef code
mindhardt
mindhardtOP3y ago
Ok, let me elaborate This is inside a method that commands call from different threads, theoretically very often How do I properly work around EFCore working alright? Inject ServiceProvider and embrace contexts in usings? Inject DbContextFactory and use it (never seen it before)? And it is all inside a singleton service
Jayy
Jayy3y ago
Well this is ur mistake U shoudont have this Every command should get its own service scope Just like a normal asp api
mindhardt
mindhardtOP3y ago
Yeah I see Disqord does that, I wanted to refactor my commands, now they have all the code (controller, database, display) messed together in a scoped commands module
Jayy
Jayy3y ago
I've never used disqord But singletons are going to cause pain no matter what
mindhardt
mindhardtOP3y ago
I wanted to make a service for accessing database andor cache and abstract it Should I make it scoped then?
Jayy
Jayy3y ago
I mean ya lol
mindhardt
mindhardtOP3y ago
So appears a question: is IMemoryCache singleton? If I inject it into transients will it still work between them?
Jayy
Jayy3y ago
But this depends on ur d lib I memory cache is not singleton
mindhardt
mindhardtOP3y ago
Disqord works awesome with generic host, it can inject everything from serviceprovider
Jayy
Jayy3y ago
Well there ya go Use that
mindhardt
mindhardtOP3y ago
Ok, let me rephrase: If I do this this scoped, will all of them access the same IMemoryCache if it is gained from serviceprovider?
Jayy
Jayy3y ago
No, they won't You can register the cache as singleton tho Then you'll get the same cache across all the scopes
mindhardt
mindhardtOP3y ago
Do I do it like this?
mindhardt
mindhardtOP3y ago
Am sorry to take your time, but I never used IMemoryCache Wait, this is confusing I guess I will stick to a singleton service for accessing cache and scoped ones for database
Want results from more Discord servers?
Add your server