How to call method in class loaded assembly that pauses a - c#

I load my assembly dynamically, I create an instance of a UserControl View through Activator.CreateInstance.
classType = a.GetType(assembly + "." + constructor);
obj = Activator.CreateInstance(classType);
I have a ViewModel linked to the view. The ViewModel has a timer which it starts in the constructor.
I would like to dynamically call a method like Pause() and Resume() that stops and starts this timer.
My thoughts are that this method will have to be in the View's code-behind. I will keep the classType and obj around, so I can call the View's methods. However the way to go about informing the ViewModel to pause or resume from the code-behind without upsetting the MVVM is stumping me. Could use some advice.
[EDIT]
Ignore below has been open as a separate question: https://stackoverflow.com/questions/20572205/how-call-dispose-method-with-loaded-assembly
If I would like to dispose of an instance of this class. I have tried
var methodInfo = CurrentAssemblyClassType.GetMethod("Dispose");
var methodInfo = CurrentAssemblyClassType.GetMethod("Close");
methodInfo is null on both, not sure what to call.
public partial class Blank : UserControl, IDisposable
{
public Blank(String key)
{
InitializeComponent();
}
public void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
}
}
~Blank()
{
Dispose(false);
}
#region IDisposable Members
void IDisposable.Dispose()
{
Close();
}
#endregion
}

In MVVM, the View can tell the ViewModel what to do by way of "Commands"
There is nothing special about the assembly being dynamically loaded

Related

Unsubscribe event using dispose in MVVM

Actually I m trying to close my window by firing the event from my ViewModel. Everything works fine and awesome, but I know that I must unsbscribe my event to avoid memory leaks. thus I implement the IDisposable interface and I unsbscribe the event inside the Dispose method.
Below is my code :
public partial class MainWindow : Window, IDisposable
{
private MainViewModel viewModel;
public MainWindow()
{
InitializeComponent();
DataContext = viewModel = new MainViewModel();
this.viewModel.RequestClose += CloseWindow;
}
void CloseWindow(object sender, EventArgs e)
{
this.Close();
}
public void Dispose()
{
////here we need to unsubscribe the event
this.viewModel.RequestClose -= this.CloseWindow;
}
}
What I need to know :
Is that code correct
When the GC will be called and excute the dispose method
Is there a better way to do such a thing
but I know that I must unsbscribe my event to avoid memory leaks
Memory leak occurs, when short-lived object subscribes an event of long-lived objects (or static event), and does not unsubscribe later (e.g., see this answer). I suppose, that this is not your case.
When the GC will be called and excute the dispose method
GC doesn't call IDisposable.Dispose (e.g., see this answer). At all.
If you haven't any code, that calls MainWindow.Dispose explicitly, it will be called never.
Is there a better way to do such a thing
I'd avoid IDisposable and events. Attached behavior here is more convenient, IMO (at least, this is reusable):
public static class WindowClosingBehavior
{
public static bool GetIsClosingInitiated(DependencyObject obj)
{
return (bool)obj.GetValue(IsClosingInitiatedProperty);
}
public static void SetIsClosingInitiated(DependencyObject obj, bool value)
{
obj.SetValue(IsClosingInitiatedProperty, value);
}
public static readonly DependencyProperty IsClosingInitiatedProperty = DependencyProperty.RegisterAttached(
"IsClosingInitiated",
typeof(bool),
typeof(WindowClosingBehavior),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsClosingInitiatedChanged));
private static void IsClosingInitiatedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
var window = target as Window;
if (window != null && (bool)e.NewValue)
{
window.Close();
}
}
}
Somewhere in window's XAML:
behaviors:WindowClosingBehavior.IsClosingInitiated="{Binding IsClosingInitiated}"
where IsClosingInitiated is a property from view model:
public class SomeViewModel
{
// ...
private void Foo()
{
// ...
IsClosingInitiated = true;
}
}
You only need to unsubscribe events when the source and the handler have different lifetimes, otherwise they both go out of scope at the same time and they are garbage collected together.
So in this case IDisposable is not needed. Anyway if you implement IDisposable you need to explicitly call it, otherwise you don't have control about when it is called.
Actually when the Window.CloseWindow subscribe to the event, it makes the view model point to the window.
The reverse is also true because there is a ViewModel field in the Window.
Both window and view model reference to each other.
If there is no other reference to them, garbage collection will make the job.
Dispose will be called if some code calls it.
To my knowledge, it won't happen, unless you surround the creation of the windows with a using or explicitly call Dispose
The best way here is to not implement IDisposable / Dispose : keep it simple.
Regards
I'd say using an event is a more than acceptable method of achieving this. For a more complete dispose pattern, use the following snippet:
#region IDisposable
//Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// NOTE: Delete the finalizer if this class doesn't
// own unmanaged resources itself.
~ClassName()
{
//Finalizer calls Dispose(false)
Dispose(false);
}
//The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//free managed resources (Example below)
if (managedResource != null)
{
managedResource.Dispose();
managedResource = null;
}
}
//Free native resources if there are any. (Example below)
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
}
#endregion
In your case, your dispose method will be this:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MainWindow()
{
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (viewModel != null)
{
viewModel.RequestClose -= CloseWindow;
viewModel.Dispose();
viewModel = null;
}
}
}
As pointed out by Dennis, you'll need to keep the finalizer to ensure that Dispose gets called when the MainWindow is closed, for example in the event of the application being exited.

c# wont use an new overrided method in the base class

I have something like this
class Super{
public event EventHandler MyEvent;
public void Enable(){
MyEvent+=AtEvent;
}
public void Disable(){
MyEvent-=AtEvent;
}
protected void AtEvent(object sender,EventArgs e){
AllThatJazz();
}
}
class Child:Super{
protected new void AtEvent(object sender,EventArgs e){
try{
base.AtEvent(sender,e);
}catch(ObjectDisposedException){}
}
}
class Program{
public static void Main(){
Child c = new Child();
c.Enable();
}
}
c.Enable() attaches the base class's event handler to MyEvent, not the Child's new AtEvent method. Can somebody explain this?
I appreciate suggestions for alternatives, but note that Super is in a separate assembly.
AtEvent is not virtual, it's sealed. You're calling it from a method in the base class, so it is going to be statically bound to that specific implementation of the method. It would need to be virtual (and overridden instead of shadowed) to call the most-derived implementation of that method, or it would need to be called from a reference to the object that was statically typed to Child, which is not currently the case at the place in which you call AtEvent.

Using statement in every function -> convert to class field with proper cleanup?

Basically I have a few functions that look like this:
class MyClass
{
void foo()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
void bar()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
}
Under the assumption I can use the same resource instead of a different one [instance] in every function is it ok practice in regard to cleanup and such to do this?:
class MyClass
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
~MyClass()
{
helper.Dispose();
}
}
No, do not add a destructor (Finalizer).
You can reuse the resource but then your class has to implement IDisposable.
sealed class MyClass : IDisposable
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
//~MyClass()
public void Dispose()
{
helper.Dispose();
}
}
And now you have to use MyClass instances in a using block. It self has become a managed resource .
A destructor is of no use, whenever a MyClass instance is being collected the associated helper object will also be in the same collection. But having a destructor still incurs considerable overhead.
The standard pattern for IDisposable uses a virtual void Dispose(bool disposing) method but when making the class sealed you can use the minimalistic implementation above.
In .NET you don't know when (or whether) finalizer is called at all.
Instead, explicitly indicate that your class is to be disposed of by implementing IDisposable:
(This is exactly what SomeHelper does)
class MyClass : IDisposable
{
readonly SomeHelper helper = CreateHelper();
// any method can use helper
public void Dispose()
{
helper.Dispose();
}
}
using(var myObj = new MyClass()) {
// at the end, myObj.Dispose() will trigger helper.Dispose()
}
I used readonly to ensure helper doesn't get re-assigned somewhere else in the class, but this really doesn't matter if you're careful.
You must be extra careful to never set it to null, or your Dispose will throw an exception. If the field is protected, you can check for nullity before calling Dispose on it so you know you're playing safe.
You can share such a resource during the lifetime of your object, in which case it is recommended that you implement IDisposable.
No, it is not. You don't know when the finalized will un. Also, if your resource is managed, it will be disposed of at some point without the finalized.
If you don't want to use using all the time, perhaps ou can use it once around many functions.
You don't need to override the finalizer in your object, which you have shown in your second code sample by ~MyClass().
You will need to implement the IDisposable pattern. You haven't been explicit in your question if you are using managed and unmanaged resources, but here's a quick sample for a managed resource. Stackoverflow has a myriad of examples on this. Reed Copsey also has a good series on it, and you can start here.
class MyClass : IDisposable
{
private bool _Disposed;
private SomeHelper _Helper;
protected virtual void Dispose()
{
this.Dispose(true);
}
public void Dispose(bool disposing)
{
if (_!Disposed && disposing)
{
if (_Helper != null)
_Helper.Dispose();
_Disposed = true;
}
}
}
The convention is that if your class owns an IDisposable object it should also implement IDisposable. So rather than implementing a finalizer your class should implement IDisposable and dipose of the helper there.
One problem with implementing the finalizer is that you have no control over when it's being called. The disposable pattern gives you a more deterministic way of cleaning up resources.

how do i dispose of a class that is a property of another class?

How do I dispose of DC in this situation where DC is a property of Service class?
class Service()
{
public DataContext DC= new DataContext();
public void SomeMethod()
{
DC is used here.
}
public void SomeOtherMethod()
{
DC is also used here.
}
}
Your "Service" class should implement IDisposable if it maintains references to unmanaged resources. This tells clients of your class that they need to call Dispose() on instances of "Service". You can call Dispose() on "DC" in your class' Dispose() method.
class Service : IDisposable
{
public DataContext DC= new DataContext();
public void Dispose( )
{
DC.Dispose( );
}
}
As an aside, I would avoid creating public fields in C# where properties are the common idiom.
Make your Service IDisposable and dispose the DataContext in the Dispose method. It is a common pattern.
You could implement IDisposable on your hosting class and dispose of the hosted DC in the Dispose() method. Then use the hosting class using 'using'..
using(Service service = new Service())
{
// do something with "service" here
}
Your Service class should take care of disposing DataContext.
Use the standard Dispose pattern.
Implement IDisposable:
MSDN: Implementing a Dispose Method
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
if (!_disposed)
{
if (disposing) {
if (DC != null)
DC.Dispose();
}
// Indicate that the instance has been disposed.
DC = null;
_disposed = true;
}
}

DI: Handling Life of IDisposable Objects

So I'm working on my DI/IoC Container OpenNETCF.IoC and I've got a (reasonable) feature request to add some form of lifecycle management for IDisposable items in the container collections.
My current thinking is that, since I can't query an object to see if it's been disposed, and I can't get an event for when it's been disposed, that I have to create some form of wrapper for objects that a developer wants the framework to manage.
Right now objects can be added with AddNew (for simplicity sake we'll assume there's only one overload and there is no Add):
public TTypeToBuild AddNew<TTypeToBuild>() { ... }
What I'm considering is adding a new method (well group of them, but you get the picture):
public DisposableWrappedObject<IDisposable> AddNewDisposable<TTypeToBuild>()
where TTypeToBuild : class, IDisposable
{
...
}
Where the DisposableWrappedObject looks like this:
public class DisposableWrappedObject<T>
where T : class, IDisposable
{
public bool Disposed { get; private set; }
public T Instance { get; private set; }
internal event EventHandler<GenericEventArgs<IDisposable>> Disposing;
internal DisposableWrappedObject(T disposableObject)
{
if (disposableObject == null) throw new ArgumentNullException();
Instance = disposableObject;
}
~DisposableWrappedObject()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
lock(this)
{
if(Disposed) return;
EventHandler<GenericEventArgs<IDisposable>> handler = Disposing;
if(handler != null)
{
Disposing(this, new GenericEventArgs<IDisposable>(Instance));
}
Instance.Dispose();
Disposed = true;
}
}
}
Now, when an items gets added to the container via AddNewDIsposable, an eventhandler is also added so that when it gets Disposed (via the wrapper) the framework removes it from the underlying collection.
I actually have this implemented and it's passing the unit tests, but I'm looking for opinions on where this might be broken, or how it might be made more "friendly" to the consuming developer.
EDIT 1
Since there was a question on how the Disposing event is used, here's some code (trimmed to what's important):
private object AddNew(Type typeToBuild, string id, bool wrapDisposables)
{
....
object instance = ObjectFactory.CreateObject(typeToBuild, m_root);
if ((wrapDisposables) && (instance is IDisposable))
{
DisposableWrappedObject<IDisposable> dispInstance = new
DisposableWrappedObject<IDisposable>(instance as IDisposable);
dispInstance.Disposing += new
EventHandler<GenericEventArgs<IDisposable>>(DisposableItemHandler);
Add(dispInstance as TItem, id, expectNullId);
instance = dispInstance;
}
....
return instance;
}
private void DisposableItemHandler(object sender, GenericEventArgs<IDisposable> e)
{
var key = m_items.FirstOrDefault(i => i.Value == sender).Key;
if(key == null) return;
m_items.Remove(key);
}
Maybe I'm missing something, but why add new methods to the API? When an object is added to the container, you could as-cast to check if it's IDisposable and handle it appropriately if so.
I'm also wondering if you need the destructor. Presuming the container is IDisposable (like Unity's), you could just implement the Basic Dispose Pattern and save a lot of GC overhead.
Some questions that may be applicable:
How do you reconcile IDisposable and IoC?
Can inversion of control and RAII play together?

Categories