Does Dart/Flutter have the concept of weak references? - memory-leaks

I'm in the early stages of learning Dart & Flutter. I'm looking at how to implement an eventbus, which works fine, but I've noticed that Widgets (and/or their associated state) hold a strong reference to the (global) eventbus, causing a memory leak. The solution is to cancel the subscription in the widget-state's dispose method, but I'd like to know if there's a better approach (I'm coming from Swift which allows variables to be declared as 'weak').
EDIT
I ended up subclassing the state as follows... any better suggestions?
abstract class CustomState<T extends StatefulWidget> extends State {
List<StreamSubscription> eventSubscriptions = [];
void subscribeToEvent(Object eventClass, Function callback) {
StreamSubscription subscription = eventBus.on(eventClass).listen(callback);
eventSubscriptions.add(subscription);
}
void dispose() {
super.dispose();
eventSubscriptions.forEach((subscription) => subscription.cancel());
eventSubscriptions = null;
}
}
class MyEvent {
String text;
MyEvent(this.text);
}
class _MyHomePageState extends CustomState<MyHomePage> {
#override
void initState() {
super.initState();
subscribeToEvent(MyEvent, onEventFired);
}
void onEventFired(event) {
print('event fired: ${event.runtimeType} ${event.text}');
}
}

Dart doesn't provide weak reference feature.
An Expando has a weak reference behavior though.
Not sure if this is of use in your use case.
https://api.dartlang.org/stable/1.24.3/dart-core/Expando-class.html
https://groups.google.com/a/dartlang.org/forum/m/#!topic/misc/S7GGxegtJe4
What is the Dart "Expando" feature about, what does it do?
https://github.com/dart-lang/sdk/issues/16172
I sometimes use a Mixin that provides a list where I can add subscriptions and a dispose methode that cancels all subscriptions and add it to widgets and other classes where I need it.

As of 2020, I'd like to add to Günter's answer that I've just published a package that goes as close as possible to a weak-reference by implementing a weak-map and a weak-container, as well as cache functions that take advantage of weak references.
https://pub.dev/packages/weak_map
It's much easier to use than an Expando (it uses Expando internally).

Since dart 2.17 you can use WeakReference.
Any object wrapped in WeakReference(obj) is not kept from being garbage collected.
You access the object via the target property which becomes null when the object got garbage collected.
final myWeakRef = WeakReference(ExampleObj());
// access obj, may be null
print(myWeakRef.target);

Related

Template methode in threaded contexts

Let's say we have a template method that looks like this
abstract class Worker
{
public void DoJob()
{
BeforJob()
DoRealJob();
AfterJob();
}
abstract void DoRealJob();
}
subclasses that inherit from the Wroker classe should implemente the DoRealJob() method,
when the implementation is running under the same thread everything is fine, the three part of the DoJob() method get executed in this order
BeforJob()
DoRealJob()
AfterJob()
but when DoRealJob() runs under another thread, AfterJob() may get executed before DoRealJob() is completed
my actual solution is to let the subclasses call AfterJob() but this doesn't prevent a subclass from forgetting to call it, and we loose the benefit of a template method.
are there other ways to get consistent call order despite the fact the DoRealJob() is blocking or not?
You can't get both the simple inheritance(signature and hooking) and support asynchronous operations in your code.
These two goals are mutually exclusive.
The inheritors must be aware about callback mechanisms in either direct (Tasks, async) or indirect (events, callback functions, Auto(Manual)ResetEvents or other synchronization constructs). Some of them new, some old. And it is difficult to say which one will be better for the concrete case of use.
Well, it may look like there is a simple way with multithreaded code, but what if your DoRealJob will actually run in another process or use some remote job queuing, so the real job will be executed even outside your app?
So:
If you really consider that your class will be used as the basis for some
async worker, then you should design it accordingly.
If not - do not overengineer. You can't consider any possible
scenario. Just document your class well enough and I doubt that
anyone will try to implement the DoRealJob asynchronously,
especially if you name it DoRealJobSynchronously. If someone tries to
do it then in that case your conscience can be pristinely clean.
EDIT:
Do you think it would be correct if I provide both versions, sync and
async, of DoRealJob and a flag IsAsynchronous so I can decide which
one to call
As I have already said I don't know your actual usage scenarios. And it is unrealistic to consider that the design will be able to effectively handle all of them.
Also there are two very important questions to consider that pertain to your overall Worker class and its DoJob method:
1) You have to determine whether you want the DoJob method to be synchronous or asynchronous, or do you want to have both the synchronous and asynchronous versions? It is not directly related to your question, but it is still very important design decision, because it will have great impact on your object model. This question could be rephrased as:
Do you want the DoJob method to block any actions after it is called until it does its job or do you want to call it as some StartJob method, that will just launch the real processing but it is up to other mechanisms to notify you when the job has ended(or to stop it manually):
//----------------Sync worker--------------------------
SyncWorker syncWorker = CreateSyncStringWriter("The job is done");
Console.WriteLine("SyncWorker will be called now");
syncWorker.DoJob(); // "The job is done" is written here
Console.WriteLine("SyncWorker call ended");
//----------------Async worker--------------------------
Int32 delay = 1000;
AsyncWorker asyncWorker = CreateAsyncStringWriter("The job is done", delay);
Console.WriteLine("AsyncWorker will be called now");
asyncWorker.StartDoJob(); // "The job is done" won't probably be written here
Console.WriteLine("AsyncWorker call ended");
// "The job is done" could be written somewhere here.
2) If you want DoJob to be async(or to have async version) you should consider whether you want to have some mechanisms that will notify when DoJob finishes the processing - Async Programming Patterns , or it is absolutely irrelevant for you when or whether at all it ends.
SO:
Do you have the answers to these two questions?
If yes - that is good.
If not - refine and consider your requirements.
If you are still unsure - stick with simple sync methods.
If you, however, think that you need some async based infrastructure, then, taking into account that it is C# 3.0, you should use Asynchronouse Programming Model.
Why this one and not the event based? Because IAsyncResult interface despite its cumbersomeness is quite generic and can be easily used in Task-based model, simplifying future transition to higher .NET versions.
It will be something like:
/// <summary>
/// Interface for both the sync and async job.
/// </summary>
public interface IWorker
{
void DoJob();
IAsyncResult BeginDoJob(AsyncCallback callback);
public void EndDoJob(IAsyncResult asyncResult);
}
/// <summary>
/// Base class that provides DoBefore and DoAfter methods
/// </summary>
public abstract class Worker : IWorker
{
protected abstract void DoBefore();
protected abstract void DoAfter();
public IAsyncResult BeginDoJob(AsyncCallback callback)
{
return new Action(((IWorker)this).DoJob)
.BeginInvoke(callback, null);
}
//...
}
public abstract class SyncWorker : Worker
{
abstract protected void DoRealJobSync();
public void DoJob()
{
DoBefore();
DoRealJobSync();
DoAfter();
}
}
public abstract class AsyncWorker : Worker
{
abstract protected IAsyncResult BeginDoRealJob(AsyncCallback callback);
abstract protected void EndDoRealJob(IAsyncResult asyncResult);
public void DoJob()
{
DoBefore();
IAsyncResult asyncResult = this.BeginDoRealJob(null);
this.EndDoRealJob(asyncResult);
DoAfter();
}
}
P.S.: This example is incomplete and not tested.
P.P.S: You may also consider to use delegates in place of abstract(virtual) methods to express your jobs:
public class ActionWorker : Worker
{
private Action doRealJob;
//...
public ActionWorker(Action doRealJob)
{
if (doRealJob == null)
throw new ArgumentNullException();
this.doRealJob = doRealJob;
}
public void DoJob()
{
this.DoBefore();
this.doRealJob();
this.DoAfter();
}
}
DoBefore and DoAfter can be expressed in a similar way.
P.P.P.S: Action delegate is a 3.5 construct, so you will probably have to define your own delegate that accepts zero parameters and returns void.
public delegate void MyAction()
Consider change the DoRealJob to DoRealJobAsync and give it a Task return value. So you can await the eventual asynchronous result.
So your code would look like
abstract class Worker
{
public void DoJob()
{
BeforJob()
await DoRealJobAsync();
AfterJob();
}
abstract Task DoRealJob();
}
If you don't have .net 4.0 and don't want to us the old 3.0 CTP of async you could use the normale task base style:
abstract class Worker
{
public void DoJob()
{
BeforJob()
var task = DoRealJobAsync();
.ContinueWith((prevTask) =>
{
AfterJob()
});
}
abstract Task DoRealJob();
}

does dispose method disposes the calling object also?

I found the following code on MSDN:
public class DisposeExample
{
public class MyResource: IDisposable
{
private IntPtr handle;
private Component component = new Component();
private bool disposed = false;
public MyResource(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
disposed = true;
}
}
~MyResource()
{
Dispose(false);
}
}
public static void Main()
{
MyResource obj = new MyResource()
//obj.dispose()
}
}
Now the confusion I have here is that, if I call obj.dispose, it disposes the objects created in the class MyResources i.e. handle, component etc. But does the obj also gets removed off the heap?? Same applies with the destructor. If I don't call dispose, the destructor will be called sometime. The code inside destructor removes the contained objects. But what about the obj?
Secondly, if I don't have a destructor defined inside the class and I dont even call dispose, does the GC never come into picture here?
IDisposable exists to remove unmanaged items from your managed objects. The runtime automatically provides a destructor, this destructor here has the sole purpose of releasing unmanaged items. As soon as your object goes out of scope or is set to null and has no more references to it will eventually be cleared by the GC.
The fundamental rule I'd recommend with with IDisposable is that at any given moment in time, for every object that implements IDisposable, there should be exactly one entity which has the clearly-defined responsibility of ensuring that it will get cleaned up (almost always by calling Dispose) before it is abandoned. Such responsibility will initially belong to whatever entity calls the IDidposable object's constructor, but that entity may hand the responsibility off to some other entity (which may hand it off again, etc.).
In general, I'd guess that most programmers would be best served if they pretended finalizers and destructors did not exist. They are generally only needed as a consequence of poorly-written code, and in most cases the effort one would have to spend writing a 100%-correct finalizer/destructor and working through all the tricky issues related to threading context, accidental resurrection, etc. could be better spent ensuring that the primary rule given above is always followed. Because of some unfortunate design decisions in the Framework and its languages, there are a few situations which can't very well be handled without finalizers/destructors, but for the most part they serve to turn code which would fail relatively quickly into code which will mostly work but may sometimes fail in ways that are almost impossible to debug.

Confusion with IDisposable

I have some nagging doubts about the correct way to implement IDisposable. Consider the following scenario...
public class Foo : IDisposable {...}
public class Bar : IDisposable {
private bool disposed = false;
private readonly Foo MyFoo;
public Bar() {
this.MyFoo = new Foo();
}
public Bar(Foo foo) {
this.MyFoo = foo;
}
~Bar() {
Dispose(false);
}
protected virtual void Dispose(bool disposing) {
if (!this.disposed) {
if (disposing) {
if (MyFoo != null) {
this.MyFoo.Dispose();
this.MyFoo = null;
}
}
this.disposed = true;
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
My questions are:
1) If a class creates a disposable object, should it call the Dispose() method on that object in its own Dispose() method?
2) If a disposable object is passed to a class as a reference, should that class still call the Dispose() method on that reference object, or should it leave it to the class that created the object in the first place?
The above pattern seems to crop up quite a lot (particularly with DI), but I don't seem to be able to find a concrete example of the correct way to structure this.
Refer to Excellent MSDN article
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
1) If a class creates a disposable object, should it call the Dispose() method on that object in its own Dispose() method?
Yes it should. Otherwise also, Dispose will be called. But that will increase life of object by atleast 1 generation. This is due to the finalizer in the class definition. Refer to the article link above.
2) If a disposable object is passed to a class as a reference, should that class still call the Dispose() method on that reference object, or should it leave it to the class that created the object in the first place?
It is responsibility of caller (more specifically the class which has created an instance) to call the Dispose method.
~Bar() {
Dispose(false);
}
Whenever you find yourself writing code like this, take a deep breath first and ask "do I actually need a finalizer?" It is extremely rare that you need one, a finalizer is only required when you take ownership of an unmanaged resource yourself.
The first litmus test is "does the finalizer actually do anything?" That's clear if you follow the code. It calls Dispose(false) and that code only does something when the argument is true. What follows is that you don't need a finalizer. This is entirely normal, finalizers is something that Microsoft worries about. They wrote the .NET framework classes that wrap an unmanaged resource. FileStream, Socket, etcetera. And above all, the SafeHandle classes, designed to wrap operating system handles. They have their own finalizer, you don't rewrite one yourself.
So without a finalizer, the code entirely collapses to the simple and correct implementation, you only need to call the Dispose() method of any disposable objects you store yourself:
public class Bar : IDisposable {
private readonly Foo MyFoo;
public Bar() {
this.MyFoo = new Foo();
}
public void Dispose() {
MyFoo.Dispose();
}
}

C# 4, COM interop and UPnP: A trying triumvirate

I'm trying to write a bit of code (just for home use) that uses UPnP for NAT traversal, using C# 4 and Microsoft's COM-based NAT traversal API (Hnetcfg.dll).
Unfortunately (or perhaps fortunately) the last time I had to do COM interop in .NET was sometime around the last ice age, and I seem to be fundamentally confused about C#'s use of dynamic types for interop and how to write a callback (so that the COM server calls my managed code).
Here's an exciting few lines of code:
// Referencing COM NATUPNPLib ("NATUPnP 1.0 Type Library")
using System;
using NATUPNPLib;
class NATUPnPExample
{
public delegate void NewNumberOfEntriesDelegate(int lNewNumberOfEntries);
public static void NewNumberOfEntries(int lNewNumberOfEntries)
{
Console.WriteLine("New number of entries: {0}", lNewNumberOfEntries);
}
public static void Main(string[] args)
{
UPnPNAT nat = new UPnPNAT();
NewNumberOfEntriesDelegate numberOfEntriesCallback = NewNumberOfEntries;
nat.NATEventManager.NumberOfEntriesCallback = numberOfEntriesCallback;
nat.StaticPortMappingCollection.Add(4555, "TCP", 4555, "192.168.0.1", true, "UPnPNAT Test");
// Presumably my NewNumberOfEntries() method should be called by the COM component about now
nat.StaticPortMappingCollection.Remove(4555, "TCP");
}
}
In the above code, the Add and Remove calls work absolutely fine. Terrific.
The trouble is, I would also like to know when the number of port mapping entries have changed, and to do so I need to register a callback interface (INATEventManager::put_NumberOfEntriesCallback), which must support the INATNumberOfEntriesCallback or IDispatch interfaces. VS2012's object browser describes INATEventManager::put_NumberOfEntriesCallback thusly:
dynamic NumberOfEntriesCallback { set; }
Right, so I was under the impression that in C# 4 I shouldn't have to decorate anything with fancy attributes and that I can register my callback simply by jamming a delegate into INATEventManager::put_NumberOfEntriesCallback in a vulgar manner and leaving .NET to worry about IDispatch and clear up the mess; but it appears that I'm terribly wrong.
So, er... What should I do to ensure my NewNumberOfEntries method is called?
I'm also slightly concerned that I can write nat.NATEventManager.NumberOfEntriesCallback = 1; or nat.NATEventManager.NumberOfEntriesCallback = "Sausages"; without an exception being thrown.
It seems that I was able to make it work. Two options - with a custom interface "INATNumberOfEntriesCallback" (which does not seem to be declared in the type library btw, you need to declare it yourself) and using plain dispatch with DispId(0). The conversion to the IDispatch/IUnknown is preformed by the framework automatically. So:
Option 1.
Declare the INATNumberOfEntriesCallback and make a callback class which implements that interface (the tricky part is Guid - it comes from the "Natupnp.h" file, and does not seem to appear to be in the type library).
// declare INATNumberOfEntriesCallback interface
[ComVisible(true)]
[Guid("C83A0A74-91EE-41B6-B67A-67E0F00BBD78")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface INATNumberOfEntriesCallback
{
void NewNumberOfEntries(int val);
};
// implement callback object
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class CallbackNewNumberOfEntries : INATNumberOfEntriesCallback
{
public void NewNumberOfEntries(int val)
{
Console.WriteLine("Number of entries changed: {0}", val);
}
}
class NATUPnPExample
{
public static void Main(string[] args)
{
var nat = new UPnPNAT();
nat.NATEventManager.NumberOfEntriesCallback = new CallbackNewNumberOfEntries();
nat.StaticPortMappingCollection.Add(4555, "TCP", 4555, "192.168.0.1", true, "UPnPNAT Test");
// Presumably my NewNumberOfEntries() method should be called by the COM component about now
nat.StaticPortMappingCollection.Remove(4555, "TCP");
}
}
Option 2.
Use plain dispatch. The documentation says that you can use dispid(0) and it should be called, with 4 (!) parameters (see the remarks section in docs). So basically the following construction seems to work in "dispatch" way:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class CallbackDisp
{
[DispId(0)]
public void OnChange(string updateType, object obj, object name, object val)
{
Console.WriteLine("{0}: {1} = {2}", updateType, name, val);
}
}
class NATUPnPExample
{
public static void Main(string[] args)
{
var nat = new UPnPNAT();
nat.NATEventManager.NumberOfEntriesCallback = new CallbackDisp();
nat.StaticPortMappingCollection.Add(4555, "TCP", 4555, "192.168.0.1", true, "UPnPNAT Test");
// Presumably my NewNumberOfEntries() method should be called by the COM component about now
nat.StaticPortMappingCollection.Remove(4555, "TCP");
}
}
I had the same problem you had, and since there isn't much help on the topic your posting helped tremendously! It wouldn't let me comment on your answer because I don't have enough points or whatever but your answer is the best, but doesn't quite work how I thought it would.
nat.NATEventManager.ExternalIPAddressCallback = new CallbackDisp();
Works, using the same dispatch, and will tell you when the external IP changes. HOWEVER,
nat.NATEventManager.NumberOfEntriesCallback = new CallbackDisp();
only reports UPnP map changes from these conditions: A.) It was added/removed by the NATUPnP instance.. In this case:
nat.StaticPortMappingCollection.Add();
OR B.) it was already mapped when the instance was created:
var nat = new UPnPNAT();
As an example, if Utorrent was running when you started your program and you you had something to block the program from exiting(Console.WriteLine();) for example.. When you exit Utorrent the callback would fire, and notify you of the map changes. Which is exactly what I wanted in the first place. However, if you re-open Utorrent, or any other app that uses UPnP it will NOT fire the callback, and will not notify you of the change.
Needless to say it has been very frustrating. If you figure it out please share! I know I can easily implement the functionality by polling the StaticPortMappingCollection at a given interval, but it seems a little 'hacky' to me.

Can ReSharper live templates do conditional code generation?

Example: I would like to have a template that inserts a method. If the class is declared sealed, then I'd like the method to be declared private. If the class is not sealed, then I'd like the method to be declared protected virtual.
Another example. If the class is inherited, and the superclass contains a method X, then call base.X(); otherwise do nothing.
Is this type of conditional processing available in ReSharper? I guess this is getting close to T4 territory but it would be really handy to be able to do this in Live Templates.
In case it matters, I'm using R# 7.
Detailed scenario
Both of these requirements came from trying to write a Live Template for the IDisposable pattern (see Implementing the Disposable Pattern Correctly). The generated code needs to be different depending on whether the class is a base class or subclass. One can define two templates, but it is not difficult to dream up other scenarios where this would be useful. Here's the code in my IDisposable template:
#region IDisposable Pattern
/// <summary>
/// Finalizes this instance (called prior to garbage collection by the CLR)
/// </summary>
~$ClassName$() {
Dispose(fromUserCode: false);
}
public void Dispose()
{
Dispose(fromUserCode: true);
GC.SuppressFinalize(this);
}
private bool disposed = false;
// Declare as private if this class is sealed.
protected virtual void Dispose(bool fromUserCode)
{
if (!disposed)
{
if (fromUserCode)
{
// ToDo - Dispose managed resources (call Dispose() on any owned objects).
// Do not dispose of any objects that may be referenced elsewhere.
}
// ToDo - Release unmanaged resources here, if necessary.
}
disposed = true;
// ToDo: Call the base class's Dispose(Boolean) method, if available.
// base.Dispose(fromUserCode);
}
#endregion
You can certainly do this. What you need is a plugin that implements the corresponding live template macro that performs the actual check.

Resources