[Proposal]: Weak keyword better memory managment #4039
-
Weak keyword better memory management
SummaryLets discuss if it possible and would be useful to add weak keyword for such scenarious: class Customer
{
weak event Action evt; // All Targets are stored by WeakReferece-s
void Run()
{
var list = new List<object>();
Action<bool> action = weak () => if (list.TryGetTarget(out List<object> lst)) lst.Count > 0; // list is captured by WeakReference-s in lambda object
}
} MotivationThis feature could improve the situation with leak memory Detailed designDrawbacksAlternativesUnresolved questionsDesign meetings |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 16 replies
-
You can already use |
Beta Was this translation helpful? Give feedback.
-
@redradist I've moved this to a dicussion. For future reference, if you want to discuss something without suggesting a concrete detailed proposal, you can do so by clicking on the "dicussions" tab, and then selecting "new discussion". |
Beta Was this translation helpful? Give feedback.
-
I'm having a difficult time understanding the proposal. Each use of Note that past proposals for syntax sugar for weak references suffered from similar issues, e.g. dotnet/roslyn#101, dotnet/roslyn#13950 |
Beta Was this translation helpful? Give feedback.
-
I can understand the desire. This is a quite common pattern, and there's a framework class to support it. https://docs.microsoft.com/en-us/dotnet/api/system.windows.weakeventmanager But it lives in WPF, and is not so efficient. |
Beta Was this translation helpful? Give feedback.
-
Just because it hasn't been explained a lots of detail yet, it's worth highlighting that anonymous delegates / lambdas make the whole concept of weak events really rather tricky. Let's take a very simple example: public class C
{
void Run()
{
var list = new List<object>();
Func<bool> action = () => list.Count > 0;
}
} If you take a look at the generated code: public class C
{
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public List<object> list;
internal bool <Run>b__0()
{
return list.Count > 0;
}
}
private void Run()
{
<>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
<>c__DisplayClass0_.list = new List<object>();
Func<bool> func = new Func<bool>(<>c__DisplayClass0_.<Run>b__0);
}
} As you can see, we've created this new class However, Life gets even worse if you do this: public class C
{
private int limit = 0;
void Run()
{
var list = new List<object>();
Func<bool> action = () => list.Count > limit;
}
} Now the generated code looks like this: public class C
{
[CompilerGenerated]
private sealed class <>c__DisplayClass1_0
{
public List<object> list;
public C <>4__this;
internal bool <Run>b__0()
{
return list.Count > <>4__this.limit;
}
}
private int limit = 0;
private void Run()
{
<>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0();
<>c__DisplayClass1_.<>4__this = this;
<>c__DisplayClass1_.list = new List<object>();
Func<bool> func = new Func<bool>(<>c__DisplayClass1_.<Run>b__0);
}
} This time, So what we want is not for Of course, it gets even harder: public class C
{
private int limit = 0;
void Run(object o)
{
Func<bool> action = () => ((List<object>)o).Count > limit;
}
} And the generated code: public class C
{
[CompilerGenerated]
private sealed class <>c__DisplayClass1_0
{
public object o;
public C <>4__this;
internal bool <Run>b__0()
{
return ((List<object>)o).Count > <>4__this.limit;
}
}
private int limit = 0;
private void Run(object o)
{
<>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0();
<>c__DisplayClass1_.o = o;
<>c__DisplayClass1_.<>4__this = this;
Func<bool> func = new Func<bool>(<>c__DisplayClass1_.<Run>b__0);
}
} Now we need to tie the lifetime of The upshot is that we have the following options:
I would love some sort of weak event support in C#, but it's a very hard problem. |
Beta Was this translation helpful? Give feedback.
Just because it hasn't been explained a lots of detail yet, it's worth highlighting that anonymous delegates / lambdas make the whole concept of weak events really rather tricky.
Let's take a very simple example:
If you take a look at the generated code: