Dispose service layer object from viewmodel wpf and c# - c#

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())

Related

C# Do I use dispose() correctly?

I studying C# IDisposable now at ASP.NET MVC
I implemented code like this,
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace DisposeTest.Controllers
{
public class TestClass : IDisposable
{
private bool disposed = false;
private Component component = new Component();
private List<string> dataItem = new List<string>();
~TestClass()
{
Dispose(disposing: false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
// DISPOSE MANAGED RESOURCE
component.Dispose();
}
// DISPOSE UNMANAGED RESOURCE
dataItem = null;
disposed = true;
}
}
public void AddItem()
{
dataItem.Add("wwwwwwwwwwwwwww");
}
}
}
using System.Web.Mvc;
namespace DisposeTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
TestClass tc = new TestClass();
tc.AddItem();
tc.dispose();
return View();
}
}
}
After When I push F5 to launch Visual studio debugger with web browser, debugger catch into destructor. But after I refreshed web browser again or hit enter browser address, debugger did not catch destructor.
I would like to know some answers.
ASP.NET MVC call destructor after every controller action?
Do I correctly used Dispose()?
Should I clear variables even private member field?
Thank you for your your adivices
ps. I added to call dispose() method after doing add();
For example. We have CatDataStore class who works with data base and implements IDisposable. This is full implements IDisposable:
class CatDataStore : IDisposable
{
//data context contains models, connection string... etc
private ApplicationDbContext _context = new ApplicationDbContext();
private bool disposed;
public async Task<bool> AddItem(Cat item)
{
await _context.Cats.AddAsync(item);
await _context.SaveChangesAsync();
return true;
}
//smth CRUD methods..
public void Dispose()
{
Dispose(true);
//GC can't eat this
GC.SupressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (disposed)
throw new ObjectDisposedException();
_context.Dispose();
}
disposed = true;
}
~CatDataStore() => Dispose(false);
}

Implementing IDisposable (the Disposable Pattern) as a service (class member)

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. :-)

What is the correct way to implement IDisposable in C#? [duplicate]

This question already has answers here:
Proper use of the IDisposable interface
(20 answers)
Closed 9 years ago.
I am trying to implement a iDisposable class in c# but the examples in msdn and stackoverflow do not works for me.
And im running a console application in visual studio 2012 framework 4.0
am I missing some using or what?
public class Foo : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
I am following this examples (hyperlinks dont works for me, dont know why):
http://msdn.microsoft.com/en-us/library/ms244737.aspx
Implementing IDisposable correctly
How to implement IDisposable properly
You can find good explanation here Proper use of the IDisposable interface
The short example:
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) {
if (!this.disposed) {
if (disposing) {
// clean resources here
}
disposed = true;
}
}
private bool disposed = false;
I think this is the standard template more or less:
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// destroy managed objects here...
}
disposed = true;
}
}
~NameOfClass()
{
Dispose(false);
}
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
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;
// Note disposing has been done.
disposed = true;
}
}
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
Source: IDisposable Interface
The standard way is to use the Dispose Pattern. See also this.
class MyClass : IDisposable
{
private bool alreadyDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// This is called by GC automatically at some point if public Dispose() has not already been called
~MyClass()
{
Dispose(false);
}
// Each derived class should implement this method and conclude it with base.Dispose(disposeManagedResourcesAlso)) call
protected virtual void Dispose(bool disposeManagedResourcesAlso)
{
if (alreadyDisposed) return;
if (disposeManagedResourcesAlso)
{
...dispose managed resources...
}
...dispose unmanaged resources...
alreadyDisposed = true;
}
}
Typical IDisposable implementation could be something like that:
public class Foo: IDisposable {
...
public Boolean IsDisposed {
get;
protected set; // <- Or even "private set"
}
protected virtual void Dispose(Boolean disposing) {
if (IsDisposed)
return;
if (disposing) {
// Release all acquired resources here
}
// You can work with structures (not objects!) here
// Hardly want you to do anything here...
IsDisposed = true;
}
public Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}

IDisposable Error in Page_Init()

Well this is really frustrating:
I had earlier posted this question in reference to Entity Framework
Using IDisposable in EF and that error is gone now, but I am unable to get this clear:
protected void Page_Init(object sender, EventArgs e)
{
try
{
String testCondition = Request.QueryString["Type"];
switch (testCondition)
{
case "A":
using (var rpt = new Report())
{
List<Class> lst= new ActionDBOClass.ActionMethod();
// other code for crstal report view
//setting datasource of the same report
}
break;
}
}
}
But then also I am getting warning that I must implement dispose on ActionMethod( In fact I have done the Idisposable implementation in the same class like:
public class ActionDBOClass:IDisposable
{
private bool _disposed = true;
public void Dispose()
{
Dispose(_disposed);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
context.Dispose();
// Dispose other managed resources.
}
//release unmanaged resources.
}
_disposed = true;
}
What else I need to do?
I have similar switch case and this is the first one I am showing.
If you don't use lst outside of the Page_Init method, call lst.Dispose() before returning. Something like:
case "A":
using (var rpt = new Report())
{
List<Class> lst= new ActionDBOClass.ActionMethod();
// other code for crstal report view
//setting datasource of the same report
lst.Dispose();
}
break;
A safer method would be to do something like using(List lst= new ActionDBOClass.ActionMethod()){... as this will ensure the Dispose is called if an exception is thrown, or to declare lst outside your try block and call Dispose in the finally block if lst != null.

Can I reference / use COM objects in my finalizer?

I have a COM type (created using tlbimp.exe) and a C# class that wraps this object. I want to perform some clean up in the finalizer for my C# wrapper. Following the guidelines here I might write something like this:
public class MyClass : IDisposable
{
private IMyComObject comObject;
public MyClass()
{
comObject = new MyComObject();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
// Be tollerant of partially constructed instances
if (comObject != null)
{
comObject.Cleanup();
// Account for object being disposed twice
comObject = null;
}
}
// Other bits go here...
}
I know that finalizers can run in any order and so I should not attempt to use any object that implements a finalizer, however as far as I can tell tlbimp generated COM types don't implement a finalizer and so the above should be OK.
I haven't been able to find any official documentation on this however, so my question is is it safe to reference and use COM objects in a finalizer?
I created a abstract com wrapper class, from which I derive all my com wrapper classes. It works very well. My original code is VB, since I need late binding (this was before C# introduced the dynamic type). The rest of my app is written in c#.
public abstract class ComWrapper : IDisposable
{
protected internal object _comObject;
protected ComWrapper(object comObject)
{
_comObject = comObject;
}
#region " IDisposable Support "
private bool _disposed = false;
protected virtual void FreeManagedObjects()
{
}
protected virtual void FreeUnmanagedObjects()
{
ReleaseComObject(_comObject);
}
private void Dispose(bool disposing)
{
if (!_disposed) {
if (disposing) {
FreeManagedObjects();
}
FreeUnmanagedObjects();
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override void Finalize()
{
Dispose(false);
base.Finalize();
}
#endregion
}
and
public static class Helpers
{
public static void ReleaseComObject(ref object o)
{
if ((o != null)) {
try {
Marshal.ReleaseComObject(o);
} catch {
} finally {
o = null;
}
}
}
public static string ToDotNetString(object comString)
{
if (comString == null) {
return string.Empty;
}
string s = comString.ToString();
ReleaseComObject(ref comString);
return s;
}
}

Categories

Resources