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);
}
Related
I am creating a server side Blazor application and want to release managed and unmanaged resource correctly. I am beginner of Blazor and not sure if what I did is correct or not. Please give me some instructions. Thanks
//This is my service for city model
namespace MyApplication.Services
{
public class BasCityService : IBasCityService, IDisposable
{
private readonly IGenericRepository<BasCity> _cityRepository;
private readonly ISysExceptionLogService _exceptionLogService;
public BasCityService(IGenericRepository<BasCity> cityRepository,
ISysExceptionLogService exceptionLogService)
{
_cityRepository = cityRepository;
_exceptionLogService = exceptionLogService;
}
public async Task<BasCity> GetByIdAsync(int id)
{
try
{
return await _cityRepository.GetByIdAsync(id);
}
catch(Exception ex)
{
await _exceptionLogService?.CreateLogAsync(ex, null,
"BasCityService.GetByIdAsync()");
return null;
}
}
//Other
............
public void Dispose()
{
_cityRepository.Dispose(true); //In GenericRepository do _dbContext.Dispose();
_exceptionLogService.Dispose();
}
}
//This is city details razor page
#page "/Base/City/CityDetails/{id:int}"
#inject IBasCityService cityService
#inject ISysExceptionLogService exceptionLogService
.........
#code {
protected override async Task OnInitializedAsync()
{
city = new BasCity();
try
{
city = await cityService?.GetByIdAsync(id);
if (city == null)
throw new NullReferenceException("Can't find City object by Id");
}
catch(Exception ex)
{
await processError?.LogError(Exception ex);
}
}
.............
//Dispose resource
// To detect redundant calls
private bool _disposedValue;
~CityDetails() => Dispose(false);
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
city = null;
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
cityService?.Dispose();
if (cityService != null) cityService = null;
exceptionLogService?.Dispose();
if (exceptionLogService != null) exceptionLogService = null;
_disposedValue = true;
}
}
}
Please tell me if CityDetails page changes to other page such as CityList page. cityService & exceptionLogService resource can be disposed correctly by the finalizer. Also what managed resource we usually need to clean up inside // TODO: dispose managed state (managed objects)? Thank you very much
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())
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);
}
}
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;
}
}
I made a class that derives from Component:
public class MyComponent: System.ComponentModel.Component
{
}
I saw that Visual Studio put this code in for me:
protected override void Dispose(bool disposing)
{
try
{
if (disposing && (components != null))
{
components.Dispose();
}
}
catch
{
throw;
}
finally
{
base.Dispose(disposing);
}
}
MyComponent has a member that is a DataSet and maybe there's some other members that implement IDisposable. What, if anything, do i need to modify with the Dispose() method to make sure things are cleaned up properly? Thanks for helping.
Change:
if (disposing && (components != null))
{
components.Dispose();
}
to be:
if (disposing && (components != null))
{
_dataset.Dispose();
components.Dispose();
}
Check any disposable member objects and dispose them if they are not null.
I came up with this class:
public class DisposableComponentWrapper : IComponent
{
private IDisposable disposable;
public DisposableComponentWrapper(IDisposable disposable)
{
this.disposable = disposable;
}
public DisposableComponentWrapper(IDisposable disposable, ISite site)
: this(disposable)
{
Site = site;
}
public void Dispose()
{
if (disposable != null)
{
disposable.Dispose();
}
if (Disposed != null)
{
Disposed(this, EventArgs.Empty);
}
}
public ISite Site { get; set; }
public event EventHandler Disposed;
}
and extension method to IContainer:
public static void Add(this IContainer container, IDisposable disposableComponent)
{
var component = (disposableComponent as IComponent);
if(component == null)
{
component = new DisposableComponentWrapper(disposableComponent);
}
container.Add(component);
}
Which might help those willing to enlist disposable resources to their forms.
Note: I'm not certain of the behaviour for IComponent.Disposed, MSDN doesn't say much about how it should be called in implementation of this interface, the documentation sounds like talking about client code registering to the event more than when it should be triggered by implementations of this interface.
Wrap the disposables in components and add them in the components collection. The generated implementation of the dispose pattern will dispose of them correctly.
public partial class MyComponent : System.ComponentModel.Component
{
private readonly System.Data.DataSet _dataSet;
public MyComponent(System.Data.DataSet dataSet)
{
_dataSet = dataSet ?? throw new System.ArgumentNullException(nameof(dataSet));
components.Add(new DisposableWrapperComponent(dataSet));
}
}
The DisposableWrapperComponent is defined thus:
using System;
using System.ComponentModel;
public class DisposableWrapperComponent : Component
{
private bool disposed;
public IDisposable Disposable { get; }
public DisposableWrapperComponent(IDisposable disposable)
{
Disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));
}
protected override void Dispose(bool disposing)
{
if (disposed) return;
if (disposing)
{
Disposable.Dispose();
}
base.Dispose(disposing);
disposed = true;
}
}
Inspired by the answer by #smoothdeveloper.
If you need to be able to reset the data set, encapsulating the lifetime management in a property works quite well.
using System;
using System.ComponentModel;
using System.Data;
public partial class MyComponent : Component
{
private const string DataSetComponentName = "dataSet";
public DataSet DataSet
{
get => (DataSet)((DisposableWrapperComponent)components.Components[DataSetComponentName])
?.Disposable;
set
{
var lastWrapper = (DisposableWrapperComponent)components.Components[DataSetComponentName];
if (lastWrapper != null)
{
components.Remove(lastWrapper);
lastWrapper.Dispose();
}
if (value != null)
{
components.Add(new DisposableWrapperComponent(value), DataSetComponentName);
}
}
}
public MyComponent(DataSet dataSet)
{
DataSet = dataSet ?? throw new ArgumentNullException(nameof(dataSet));
}
}
I used this when implementing a Windows Service that creates a disposable object in OnStart and disposes of it in OnStop.