I create a simple addIn for Power point and this is the code
pp.Application ppApplication = new pp.Application();
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
ppApplication.PresentationOpen += new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen);
ppApplication.PresentationClose += new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose);
}
void ppApplication_PresentationOpen(pp.Presentation Pres)
{
}
void ppApplication_PresentationClose(pp.Presentation Pres)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(ppApplication);
}
Power point never close if ppApplication is global. I think global com object dose not release in this way. What should I do?
Following the recommendation in this post Proper way of releasing COM objects?
1) Declare & instantiate COM objects at the last moment possible.
2) ReleaseComObject(obj) for ALL objects, at the soonest moment possible.
3) Always ReleaseComObject in the opposite order of creation.
4) NEVER call GC.Collect() except when required for debugging.
You should call
pp.Application ppApplication = new pp.Application();
within Ribbon_Load
Also you are asymmetric in your COM Instantiation and Release - you instantiate on class initialize (i.e. as a = new() in the variable declaration) but release when the presentation is closed. Closing a presentation isn't the same as closing the application - the ribbon is probably still available, and this will come to bite you.
The last point is that you never unhook the events you've hooked into the COM object, you should at least be doing
ppApplication.PresentationOpen -= new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen);
ppApplication.PresentationClose -= new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose);
to deallocate the event handlers, otherwise you have some undead references.
You should apply Dispose/Finalize pattern to free you unmanaged resource properly. This will guarantee that once your class will be disposed, all unmanaged class members (not global variables) would be released.
See https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx
using System;
using System.Runtime.InteropServices;
namespace PowerPointTestApp
{
class Program
{
static void Main(string[] args)
{
using (Container c = new Container())
{
Console.WriteLine("Opened..");
}
Console.WriteLine("Closed..");
}
}
public class Container: IDisposable
{
Microsoft.Office.Interop.PowerPoint.Application pp = new Microsoft.Office.Interop.PowerPoint.Application();
public Container()
{
pp.PresentationOpen += (pres)=>
{
//DoSomething
};
pp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
pp.Quit();
Marshal.FinalReleaseComObject(pp);
}
}
~Container()
{
Dispose(false);
}
}
}
Related
There is a class in my project called DataParse. I am making multiple connections with Ethernet. Every time a new connection is opened I create a new class as follows. Also, there is one timer in this class.
public Dictionary<string, DataParse> classDictionary = new Dictionary<string, DataParse>();
Connect Code
string IpAddress = Ip.Text;
int Port = Convert.ToInt32(PortName.Text);
var IpPort = IpAddress + ":" + Port;
classDictionary.Add(IpPort, new DataParse());
classDictionary[IpPort].DataParseRun(IpPort);
I want to destroy the created class when the connection is closed. I want to destroy the timer with the class.
I implemented a method like this to destroy the class and I failed. He goes into the timer again.
Disconnected Code
private void Events_Disconnected(object sender, ClientDisconnectedEventArgs e)
{
classDictionary[e.IpPort].Dispose();
classDictionary.Remove(e.IpPort);
}
DataParse Code
public class DataParse : IDisposable
{
private bool _disposed = false;
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
_disposed = true;
}
Timer timer;
byte[] moduleBuffer;
int writePtr;
string key;
public void DataParseRun(string IpPort)
{
moduleBuffer = new byte[50000];
writePtr = 0;
timer = new Timer(new TimerCallback(ParseTimer), null, TimeSpan.FromMilliseconds(1000), TimeSpan.FromMilliseconds(200));
key = IpPort;
}
void ParseTimer(object state)
{
var abc = key;
}
}
How can I destroy the class.
Try manually disposing the timer in the Dispose method. As far as I see the timer is never disposed.
timer.Dispose();
EDIT: Cant comment yet so Ill edit the answer. As far as I am aware you cant manually just remove your instance from memory.
It will be collected via Garbage Collector once all references to the instance are lost or unreachable - thus once you, as Trix in his answer advises, remove the instance from the Dictionary and dispose of the Timer and SafeHandle there should be nothing stopping the GC from collecting it. However when exactly this happens isn't up to you.
EDIT2: I would say so. You can try to test it by reading some huge file to String to take up 100MB and watch if the memory is let go once you dispose of everything. Apparently there is also a direct call you can make to the GC: GC.Collect() - if you call it from class I don't think it will collect that class but for testing you can call it after you dispose from the dictionary.
This question already has answers here:
does nulling a System.Threading.Timer stop it?
(4 answers)
Closed 3 years ago.
Please see example below. Even though the reference to obj is set to null, the obj is not released and Obj_Elapsed continues printing i. Notice there is no reference to the timer out of the scope of the ObjectWithTimer constructor.
public class Program
{
public static void Main(string[] args)
{
object obj = new ObjectWithTimer();
Console.ReadLine();
Console.WriteLine("obj=null");
obj = null;
Console.ReadLine();
}
}
public class ObjectWithTimer
{
private int i;
public System.Timers.Timer t;
public ObjectWithTimer()
{
t = new System.Timers.Timer(5000);
t.Elapsed += Obj_Elapsed;
t.Enabled = true;
}
public void Obj_Elapsed(object sender, ElapsedEventArgs e)
{
i++;
Console.WriteLine(i);
}
}
Setting null in this instance and/or going out of scope is not good enough, The Timer has resources it's managing and needs to be cleaned up.
Since System.Timers.Timer Implements IDisposable, ideally so should your wrapper class
public class ObjectWithTimer : IDisposable
{
// Flag: Has Dispose already been called?
private bool _disposed = false;
private int _i;
public System.Timers.Timer Timer { get; }
public ObjectWithTimer()
{
Timer = new System.Timers.Timer(5000);
Timer.Elapsed += Obj_Elapsed;
Timer.Enabled = true;
}
public void Obj_Elapsed(object sender, ElapsedEventArgs e)
{
_i++;
Console.WriteLine(_i);
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose() =>Dispose(true);
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing) Timer?.Dispose();
_disposed = true;
}
}
You should in turn then also dispose of the wrapper called at some stage, and not just set it null, the easiest way to do that is with the using statement
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
public static void Main(string[] args)
{
using(object obj = new ObjectWithTimer())
{
Console.ReadLine();
Console.WriteLine("obj=null");
}
Console.ReadLine();
}
Implementing a Dispose method
You implement a Dispose method to release unmanaged resources used by
your application. The .NET garbage collector does not allocate or
release unmanaged memory.
Note : This wasn't a complete tutorial on the IDisposable pattern, just an example. Please do your own research and diligence on this implementation
Additional Resouces
Do you need to dispose of objects and set them to null?
Why do we need Dispose() method on some object? Why doesn't the garbage collector do this work?
I'm new to IDisposable concept, I have the following scenario
facing an exception(stackover flow) when I dispose of the object.
I have to create multiple requests(parallel) to get a response from
API.
Like below:
ViewModel
public vm
{
vm(IunityContainer container) { }
public void somemethod
{
await ListofItems.ParallelForEachAsync(async item =>
{
try
{
using (var objectService = _container.Resolve<IobjectService>())
{
var response = await objectService.GeAllItem(request);
concurrentBag.Add(response);
}
}
catch (Exception e)
{
_logger.Error("Failed operation.", e);
}
},maxDegreeOfParallelism: 5);
}
}
Service.cs
public class Service : Idisposable
{
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
this.Dispose();// not sure how to dispose the service layer object which is created
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Issue: since I'm creating multiple objects by a parallel thread when end of the using (}) it throws stackoverflow exception.
solution: I wanted to dispose of "objectService" which is creating
each iteration of the foreach.
please help me resolve this issue.
The stackoverflow error comes from the fact that Dispose() calls Dispose(bool disposing) which back again calls Dispose() on so on until you reach the end of the stack.
It is not a problem of multithreading.
If you look again at the example for IDisposable object given by Microsoft https://learn.microsoft.com/fr-fr/dotnet/api/system.idisposable?view=netframework-4.8 you will see that inside if (disposing) you need to call Dispose on all IDisposable members that the class contains and not on the class itself (not this.Dispose())
The Disposable pattern is one that is re-implemented on a per class basis. So, I was looking for a way to generalize it. The problem I ran into a few years ago is that, even if you implement it as class itself, you can't have an object derive from both your Disposable implementation and from another class (C# doesn't support multi-inheritance).
The question is, how do you make a generic way to have the Disposable pattern implemented so you don't need to write it explicitly per class that implements IDisposable?
Here is the standard Disposable pattern that is generated for you by Visual Studio (VS 2015).
public class TestClass : IDisposable {
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~DisposeTest() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
My implementation
So, here is the solution I came up with.
public class DisposeService<T> where T : IDisposable {
private readonly T _disposee;
public Action<T> ManagedAction { get; set; }
public Action<T> UnmanagedAction { get; set; }
public DisposeService(T disposee, Action<T> managedAction = null, Action<T> unmanagedAction = null) {
_disposee = disposee;
ManagedAction = managedAction;
UnmanagedAction = unmanagedAction;
}
private bool _isDisposed;
public void Dispose(bool isDisposing) {
if (_isDisposed) return;
if (isDisposing && ManagedAction != null) {
ManagedAction(_disposee);
}
var hasUnmanagedAction = UnmanagedAction != null;
if (hasUnmanagedAction) {
UnmanagedAction(_disposee);
}
_isDisposed = true;
if (isDisposing && hasUnmanagedAction) {
GC.SuppressFinalize(_disposee);
}
}
}
This class allows you to create a DisposableService<> member for your class that implements IDisposable. Here is an example on how to use it when you only have managed resources.
public class TestClass : IDisposable {
protected readonly DisposeService<TestClass> DisposeService;
private readonly SafeHandle _handle;
public TestClass() {
DisposeService = new DisposeService<TestClass>(this, ps => { if (_handle != null) _handle.Dispose(); });
_handle = new SafeFileHandle(IntPtr.Zero, true);
}
public void Dispose() {
DisposeService.Dispose(true);
}
}
How it works
The DisposeService will run it's Dispose on your object's Dispose.
The DisposeService's dispose will run your Managed and Unmanaged Action that you provide on initialization (or update in derived classes).
The GC.SuppressFinalize will run automatically if an UnmanagedAction is provided.
Always make sure to create the DisposableService<> as the first action of your constructor.
So, here is an example of using this service with unmanaged resources.
public class TestClass : IDisposable {
protected readonly DisposeService<TestClass> DisposeService;
private readonly SafeHandle _handle;
public TestClass() {
DisposeService = new DisposeService<TestClass>(this,
ps => { if (_handle != null) _handle.Dispose(); },
ps => { /* Free unmanaged resources here */ });
_handle = new SafeFileHandle(IntPtr.Zero, true);
}
public void Dispose() {
DisposeService.Dispose(true);
}
~TestClass() {
DisposeService.Dispose(false);
}
}
And, an example of making a derived class from the class above.
public class TestClassDerived : TestClass, IDisposable {
private readonly SafeHandle _derivedHandle;
public TestClassDerived() {
// Copy the delegate for the base's managed dispose action.
var baseAction = DisposeService.ManagedAction;
// Update the managed action with new disposes, while still calling the base's disposes.
DisposeService.ManagedAction = ps => {
if (_derivedHandle != null) {
_derivedHandle.Dispose();
}
baseAction(ps);
};
_derivedHandle = new SafeFileHandle(IntPtr.Zero, true);
}
}
Easy peasy lemon squeezy. You keep the reference to the base's delegate and call it as part of the derived class's delegate.
Overall, should be cleaner then managing that procedural region of blarg that Microsoft has been providing since 2005...
Edit: I thought the 'this' being passed in the constructor might be a concern. But, it doesn't seem to be: Is it a bad practice to pass "this" as an argument? Just remember to put the null checks in your actions so you don't try to Dispose something that is null. :-)
Recently, I was asked to implement a class as part of a selection process. I did the program as requested. However, I failed in the test. I am really curious to know what is wrong in my solution. Any help is much appreciated. The question and my solution are given below
Question:
Implement a thread safe class which fires an event every second from construction. There need to be a function for finding the seconds elapsed. This class has to implement IDisposable and any calls to seconds elapsed function after calling dispose should fail.
My solution:
namespace TimeCounter
{
public delegate void SecondsElapsedHandler(object o, EventArgs e);
/// <summary>
/// Summary description for SecondCounter
/// </summary>
public class SecondCounter : IDisposable
{
private volatile int nSecondsElapsed;
Timer myTimer;
private readonly object EventLock = new object();
private SecondsElapsedHandler secondsHandler;
public SecondCounter()
{
nSecondsElapsed = 0;
myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OneSecondElapsed);
myTimer.Interval = 1000;
myTimer.AutoReset = false;
myTimer.Start();
}
public void OneSecondElapsed(object source, ElapsedEventArgs e)
{
try
{
SecondsElapsedHandler handlerCopy;
lock (EventLock)
{
handlerCopy = secondsHandler;
nSecondsElapsed++;
}
if (secondsHandler != null)
{
secondsHandler(this, e);
}
}
catch (Exception exp)
{
Console.WriteLine("Exception thrown from SecondCounter OneSecondElapsed " + exp.Message);
}
finally
{
if (myTimer != null)
{
myTimer.Enabled = true;
}
}
}
public event SecondsElapsedHandler AnotherSecondElapsed
{
add
{
lock (EventLock)
{
secondsHandler += value;
}
}
remove
{
lock (EventLock)
{
secondsHandler -= value;
}
}
}
public int SecondsElapsed()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException("SecondCounter");
}
return nSecondsElapsed;
}
private bool IsDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool Disposing)
{
if (!IsDisposed)
{
if (Disposing)
{
}
if (myTimer != null)
{
myTimer.Dispose();
}
}
secondsHandler = null;
IsDisposed = true;
}
~SecondCounter()
{
Dispose(false);
}
}
}
There are a few problems:
You might have been penalized for general Exception swallowing though that's not specifically related to threading issues.
There's a race condition on your timer.Dispose, as you could Dispose the timer before it is set Enabled again, resulting in an Exception.
You never set myTimer to null in Dispose.
You're accessing the managed class myTimer from the finalizer (disposing=false), which is a bad idea.
The explicit implementation of the event with locking is unnecessary. Delegates are immutable and adding/removing an event will never result in an invalid delegate state, though there can be race conditions if delegates are added/removed around the same time that the callback is fired. If you use the standard 'public event' declaration without an explicit backing private delegate, the synchronization will be handled automatically.
(minor point) If you're implementing the full Dispose pattern, it's customary to mark the Dispose(bool disposing) method as protected virtual, so that deriving classes can hook into the disposal mechanism. Better yet, mark your class sealed and you can eliminate the finalizer entirely.
Your finalizer is probably broken. It correctly passes false as the Disposing parameter. This should tell Dispose(bool) to avoid attempting to dispose other managed objects. But in that method you put:
if (Disposing)
{
}
if (myTimer != null)
{
myTimer.Dispose();
}
So you ignore the value of Disposing. This means that you call the timer's Dispose method from the finalizer thread, when that object may already have been finalized (if it has a finalizer, which it probably does). Finalizers run in an unpredictable order. It's generally recommended to not make calls to other GC-managed objects from a finalizer.
In fact, it's usually recommended that you don't write finalizers at all these days. The question didn't ask you to write one! It's unfortunate that most tutorials about IDisposable also talk about finalizers. They're different subjects.
You also catch Exception, the universal exception base class. This means you catch things like NullReferenceException. Not usually a good idea. You also log to the console, which is not worth much in a GUI or server-based application.
You can replace:
myTimer.Elapsed += new ElapsedEventHandler(OneSecondElapsed);
with:
myTimer.Elapsed += OneSecondElapsed;
Your variable naming is inconsistent. Refer to the Microsoft guidelines.