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
Related
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);
}
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. :-)
I application that uses a a Interop Com Object. Therefore I had written a wrapper class, to do the freeing in the dispose or if this is not done in the finalizer. So I can use the using keyword, to ensure a freeing is done.
Is using this pattern a good way? Or is there even a class in the Framework that is doing this for me?
class ComWrapper<T> : IDisposable
{
private readonly T comObject;
private bool disposed = false;
public ComWrapper(T comObject)
{
this.comObject = comObject;
}
~ComWrapper()
{
this.Dispose(false);
}
public T ComObject
{
get
{
return this.comObject;
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
Marshal.FinalReleaseComObject(this.comObject);
}
}
I personally wouldn't recommend this because it seems somewhat pointless. But, I would recommend having a static class called Utility, with this method:
public static void disposeComObject<T>(ref T comObject)
{
if(Marshal.IsComObject(comObject) && comObject != null)
{
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Workbook))
{
((Microsoft.Office.Interop.Excel.Workbook))comObject.Save();
((Microsoft.Office.Interop.Excel.Workbook))comObject.Close();
}
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Application))
{
((Microsoft.Office.Interop.Excel.Application))comObject.Quit();
}
Marshal.ReleaseComObject(comObject);
comObject = null;
}
}
Now From Code, you can call this like so
...
Microsoft.Office.Interop.Excel comObject = null;
try{
//Open comObject
//Here I would call some functions, and have nested exceptions
}
catch(nestedException err)
{
//Handle at your discretion
}
finally{
Utility.disposeComObject(ref comObject);
}
This is specific to the Excel Namespace, but adjusting it should be easy enough.
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;
}
}