C
C#2y ago
starlss

✅ I'm trying to understand WPF's source code. What is a WeakReference

WeakReference is a class that probably has applications other than in WPF (in particular, I'm trying to understand the Dispatcher class, wich I believe has to do with thread safety, but easiest things first). Can someone explain to me what is a WeakReference? The code of the class itself is not extensive, but it uses another concept I'm not comfortable with yet: IntPtr, and lots of attributes. Here's a link to WeakReference.cs https://referencesource.microsoft.com/mscorlib/system/weakreference.cs.html#https://referencesource.microsoft.com/mscorlib/system/weakreference.cs.html
19 Replies
333fred
333fred2y ago
A WeakReference is a reference to an instance of a class that does not keep that instance alive
starlss
starlssOP2y ago
Why the IntPtr?
333fred
333fred2y ago
All references are pointers
starlss
starlssOP2y ago
Ok, so if the only thing referencing an instance in memory is WeakReference, the GC will collect the object regardless?
333fred
333fred2y ago
Correct It specifically does not keep the object alive
starlss
starlssOP2y ago
What are the situations in which that behavior is desirable?
333fred
333fred2y ago
Well, plenty of them. For example, let's take BindingBase.EnableThreadSynchronization That's a UI method that tells graphics libraries (like WPF or MAUI) that they need to access a specific collection using a given lock But they don't want that mapping to force the collection to stay alive: if the collection is unreferenced by any other locations, then the mapping can go away If they used regular references though, that mapping would force the collection to stay alive, consuming memory for no purpose
starlss
starlssOP2y ago
ok, I think I understand it a bit more. The swarm of attributes is still very confusing.
333fred
333fred2y ago
Don't worry about the attributes They're not relevant to you I would also not recommend using referencesource, that's the old .NET Framework code https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/WeakReference.cs,985a18841b9c6087 is the modern .NET version
starlss
starlssOP2y ago
ok, alright, thanks. That seems much better. No more extern definitions I think
333fred
333fred2y ago
Don't forget to $close the thread if there are no more questions
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered
starlss
starlssOP2y ago
wait, how likely do you think it will be for me to use WeakReferences? You see, I'm making a monogame, and I'm taking inspiration from WPF for the UI. I want to understand the entire UI and be able to simplify it and "implement it" in monogame
333fred
333fred2y ago
Unlikely They're a very specialized tool
starlss
starlssOP2y ago
ok thanks a lot! can I close now?
333fred
333fred2y ago
Sure, it's your thread 🙂
starlss
starlssOP2y ago
thank you
hime
hime2y ago
I've used it for memoization where the results are stored for that object as a weak reference https://stackoverflow.com/a/53299290
private static readonly ConditionalWeakTable<object, ConcurrentDictionary<string, object>> WeakCache = new();

public static TResult Memoized<T, TResult>(
this object context, T arg, Func<T, TResult> f,
[CallerMemberName] string? cacheKey = null) where T : notnull
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (cacheKey == null) throw new ArgumentNullException(nameof(cacheKey));

var objCache = WeakCache.GetOrCreateValue(context);

var methodCache = (ConcurrentDictionary<T, TResult>) objCache
.GetOrAdd(cacheKey, _ => new ConcurrentDictionary<T, TResult>());

return methodCache.GetOrAdd(arg, f);
}
private static readonly ConditionalWeakTable<object, ConcurrentDictionary<string, object>> WeakCache = new();

public static TResult Memoized<T, TResult>(
this object context, T arg, Func<T, TResult> f,
[CallerMemberName] string? cacheKey = null) where T : notnull
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (cacheKey == null) throw new ArgumentNullException(nameof(cacheKey));

var objCache = WeakCache.GetOrCreateValue(context);

var methodCache = (ConcurrentDictionary<T, TResult>) objCache
.GetOrAdd(cacheKey, _ => new ConcurrentDictionary<T, TResult>());

return methodCache.GetOrAdd(arg, f);
}
333fred
333fred2y ago
Dammit man, you've unarchived the thread
Want results from more Discord servers?
Add your server