I have project that is running just fine. However I am getting a CA1063 error and before I suppress I want to see if I am implement Dispose incorrectly.
It starts with an interface I have defined:
public interface IAttributeRepository
{
IDataTransaction BeginTransaction();
Task<IQueryable<AttributeValue>> GetAttributeValues(int parentId);
...etc....
}
Notice that anything implementing this interface must also implement IDataTransaction so here that is:
public interface IDataTransaction : IDisposable
{
void Commit();
void RollBack();
}
Now I have defined two types of SQL interactions in my repository layer. Simple one and then those that should be wrapped in a transaction.
The transaction one is what we care about and it is defined as a private class member var as such:
private DBTransaction _dbTransaction;
The class DBTransaction looks like this:
(DbTransaction is a Msoft object in System.Data.Entity)
public class DBTransaction : IDataTransaction
{
DbContextTransaction _dbcontextTrans;
public DBTransaction(DbContextTransaction dbcontexttrans)
{ _dbcontextTrans = dbcontexttrans; }
public void Commit()
{ _dbcontextTrans.Commit(); }
public void RollBack()
{ _dbcontextTrans.Rollback(); }
public void Dispose()
{ _dbcontextTrans.Dispose(); }
}
Finally in a repository class it would be used like this:
public class AttributeRepository : IAttributeRepository
{
public IDataTransaction BeginTransaction()
{
var trans = _DataContext.Database.BeginTransaction(IsolationLevel.ReadCommitted);
_dbTransaction = new DBTransaction(trans);
return _dbTransaction;
}
public async Task<IQueryable<Data.Attribute>> GetAttribute_with_AttributeValues(int id)
{
using (var trans = this.BeginTransaction())
{
//execute sql code you want wrapped in a transaction
//rollback, commit etc based upon result
trans.Commit();
}
}
}
As I mentioned the code executes correctly I'm just not sure I understand why code analysis is telling me my dispose needs correcting and before I just suppress it I want to verify with those far more knowledgeable than I.
TIA
Useful info here: Framework Design Guidelines - Dispose Pattern
This is the pattern I would follow when implementing IDisposable on the DBTransaction class:
public class DBTransaction : IDataTransaction
{
....
~DBTransaction() {
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if(_disposed) return;
try
{
// DISPOSE OF UN-MANAGED RESOURCES HERE
if(disposing)
{
// Dispose objects here
_dbcontextTrans.Dispose();
}
}
finally
{
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
...
}
If you are deriving from a base class that implements IDisposable and has a virtual dispose method, then I would do this:
protected override void Dispose(bool disposing)
{
if(_disposed)
return;
try
{
// DISPOSE OF UN-MANAGED RESOURCES HERE
if(disposing)
{
// Dispose objects here
}
}
finally
{
_disposed = true;
base.Dispose(disposing);
}
}
This is very similar to the normal Dispose(bool disposing), but in the finally block I call base.Dispose(disposing).
EDIT #1:
Updated to take into account suggestion from #juharr.
Related
I have an application, connecting to some databases. After first execution the app takes 300Mb(some data is loading from databases), and it's OK. But after pushing button "Refresh" refresh-method is called, in which I reassign old collections with new ones and the problem is that they after loading new data - old data is still taking memory, so after some forced resfreshes it can take up to 2Gb.
I've tried to force GC with different options - nothing happened. GC doesn't think that my collections need to be fully updated and old data must be destroyed.
I've decided to make my own Disposable collection, which inherits from List or Collection and implements IDisposable[1]. Then I've gone throw all classes, which contain in such collections and implemented IDisposable(with and without destructors), too.
I've used using() construction to clear those collections[2], but the result was that collections have become empty, but still have taken memory.
Using profiling program, I saw that Gen0 objects amount grows each time I do refreshing. After 10 refreshes there were from 120 to 580 such objects, which GC couldn't clear.
EDIT:
DataContext.
UnitOfWork.
Repostitory.
Registration of repository and service of repository.
Method in service for getting data.
Declaring service using Bootstrapper and using it to get the data.
So 8 is in Refresh method, and data is reassignes each refresh.
[1]
public class DisposableList<T> : List<T>, IDisposable where T :
IDisposable
{
public DisposableList()
{
}
public DisposableList(T instance)
{
Add(instance);
}
public DisposableList(IEnumerable<T> instances)
{
AddRange(instances);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (T item in this)
{
item.Dispose();
}
}
}
public void Dispose()
{
Dispose(true);
}
~DisposableList()
{
}
}
[2]
using (Resources = new DisposableList<Resources>())
{
}
[3]
public partial class MyDataContext : DbContext, IMyDataContext
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext(string connectionString)
: base(connectionString)
{
try
{
if (!Database.Exists())
{
throw new Exception($"Нет соединения с базой данных
{Database.Connection.Database}");
}
}
catch (Exception ex)
{
throw ex;
}
}
public IDbSet<Table> Table { get; set; }
}
[4]
public class UnitOfWork : IUnitOfWork
{
DbContext _dataContext;
IRepository[] _repositories;
readonly object _locked = new object();
public UnitOfWork(DbContext dataContext, params IRepository[]
repositories)
{
_dataContext = dataContext;
_repositories = repositories;
EFContextHelper.SetContext(_repositories, dataContext);
}
public virtual void SaveChanges()
{
try
{
lock (_locked)
{
_dataContext.SaveChanges();
}
}
catch (DbUpdateConcurrencyException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
}
public virtual bool HasChanges()
=> _dataContext.ChangeTracker.HasChanges();
public virtual void Rollback()
{
lock (_locked)
{
foreach (DbEntityEntry entry in
_dataContext.ChangeTracker.Entries())
{
switch (entry.State)
{
case EntityState.Detached: break;
case EntityState.Unchanged: break;
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Deleted:
entry.State = EntityState.Unchanged;
break;
case EntityState.Modified:
entry.CurrentValues.SetValues(entry.OriginalValues);
entry.State = EntityState.Unchanged;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
#region IDispose
bool _disposed;
public virtual void Dispose()
{
if (_disposed) { return; }
foreach (var repo in _repositories)
{
repo.Dispose();
}
_dataContext?.Dispose();
_dataContext = null;
_disposed = true;
}
[5]
public interface IRepository<TEntity> : IRepository where TEntity : class
{
TEntity Create();
void Delete(TEntity entity);
void Delete(IEnumerable<TEntity> entities);
void AddOrUpdate(TEntity entity);
void Attach(TEntity entity);
void Reload(TEntity entity);
void Detach(TEntity entity);
}
[6]
builder.RegisterType<Service>().As<IService>();
builder.RegisterType<Repository>).As<Repository>;
[7]
GetData()
{
using (_UnitOfWorkFactory.Create(_repository))
{
var data = _repository.Get();
}
}
[8]
var service = Bootstrapper.Container.Resolve<IService>();
var data = service.GetData();
So I need my app to use such amount of memory, which is used after first execution. I want my old data to be destroyed and new data to take old data place.
I have taken over the coding of a software and the way it is currently done, I am not sure that the Dispose() method in the UnitOfWorks is getting called. I have noticed that my SQL service tends to stop after a while (days) saying that all connections are being used up.
I would like to know if the below code is properly done and if not, how I can go about rectifying so that it calls the dispose() method.
UnitOfWorks.cs
public class UnitOfWorks
{
private KaprukaEntities context;
private GenericRepository<Transaction> transactionRepository;
private bool disposed;
public GenericRepository<Transaction> TransactionRepository
{
get
{
if (this.transactionRepository == null)
this.transactionRepository = new GenericRepository<Transaction>(this.context);
return this.transactionRepository;
}
}
public UnitOfWorks(KaprukaEntities entities)
{
this.context = entities;
}
public void Save()
{
this.context.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed && disposing)
this.context.Dispose();
this.disposed = true;
}
public interface IDisposable
{
void Dispose();
}
}
The UnitOfWorks is getting called by a service class.
TransactionService.cs
public class TransactionService
{
private UnitOfWorks _unitOfWork;
private KaprukaEntities entities;
public TransactionService(UnitOfWorks unitOfWork)
{
this._unitOfWork = unitOfWork;
this.entities = new KaprukaEntities();
}
public bool Add(Transaction entity)
{
this._unitOfWork.TransactionRepository.Add(entity);
this._unitOfWork.Save();
var er = this.entities.GetValidationErrors();
return true;
}
public bool Update(Transaction entity)
{
this._unitOfWork.TransactionRepository.Update(entity);
this._unitOfWork.Save();
return true;
}
public bool Delete(Transaction entity)
{
this._unitOfWork.TransactionRepository.Delete(entity);
this._unitOfWork.Save();
return true;
}
public IEnumerable<Transaction> GetAll()
{
return this._unitOfWork.TransactionRepository.GetAll();
}
public IEnumerable<Transaction> GetAll(Expression<Func<Transaction, bool>> filter, Func<IQueryable<Transaction>, IOrderedQueryable<Transaction>> orderBy, string includeProperties)
{
return this._unitOfWork.TransactionRepository.Get(filter, orderBy, includeProperties);
}
}
The way this is getting called is as follows:
There is a file named updateTransaction.aspx and in its code behind, the code calls the service as such:
updateTransaction.aspx
TransactionService TransServ = new TransactionService(new UnitOfWorks(new KaprukaEntities()));
var TransDetails = TransServ.GetAll(x => x.TransactionID == intTID, null, "").SingleOrDefault();
I can't see any code to close or dispose anything.
Your transactionservice constructor creates an extra db context, when one is already in the unit of work class:
this.entities = new KaprukaEntities();
Is it possible to mark a exception as solved in Dispose method of Token class? E.g.:
//code before
using(var e = new Token()){
//..
throw new Exception();
//..
}
//code after
What I need is to void exception and continue with code after.
It does not matter if Exception occurred. I know that I can use try/catch, but in this case, I would like to go around if it possible.
I am detecting exception in the by:
bool isExceptionOccurred = Marshal.GetExceptionPointers() != IntPtr.Zero || Marshal.GetExceptionCode() != 0;
The best way to do that is to use a catch block, because that's what it's there for. Don't try to shoehorn your business requirements into the language, use the language to write what you need.
Create an abstraction layer that handles your "don't leak exceptions" requirement. For example:
public sealed class ExceptionGuard<T>:IDisposable where T:IDisposable
{
private readonly T instance;
public bool ExceptionOccurred { get; private set; }
public ExceptionGuard(T instance) { this.instance = instance; }
public void Use(Action<T> useInstance)
{
try
{
useInstance(instance);
}
catch(Exception ex)
{
this.ExceptionOccurred = true;
// Hopefully do something with your exception
}
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (disposing)
{
this.instance.Dispose();
}
}
}
After that, it's a fairly simple matter to consume and inspect.
var guard = new ExceptionGuard(new Token());
using (guard)
{
guard.Use(token => /* Do something with your token */ );
}
if (guard.ExceptionOccurred)
{
// React accordingly to this
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a class MyClass. I want to create MyClass instance in using statement and to operation something 1 in constructor, but if instance is created as nested in using statement with other instance of MyClass I want to do something 2. I have no idea how to check it. I thought about static class which check if current code statement was colled from using statement which other instance of MyClass, but i don't know how check it.
public class MyClass : IDisposable
{
public MyClass()
{
if(condition)
//do something 1
else
//do something 2
}
public void Dispose()
{
//do something
}
}
using (var mc = new MyClass()) //do something 1 in constructor
{
using (var mc1 = new MyClass()) //do something 2 in constructor
{
using (var mc2 = new MyClass()) //do something 2
{
}
}
using (var mc3 = new MyClass()) //do something 2 in constructor
{
}
Edit:
I try to do some kind of scope. It shoud be some bigger scope then TransactionScope. In my scope i want to have fiew TransactionScopes. I want to use in whole scope the same connection with database without returning it to connection pool. So when i create the major scope in using statement I want to get new connection from pool, but if i created nested using block with my scope i want to use connection from major scope. Nested is posiible because in may major using block i can run methods thats contain another using block with my scope.
The simple answer to your question is: you can't.
using is pure syntactic sugar. A typical using statement:
using (MyDisposableClass a = GetMyDisposableClass())
{
// ...
}
Gets translated directly into this:
MyDisposableClass a = null;
try {
a = GetMyDisposableClass();
// ...
}
finally {
if (a != null) a.Dispose();
}
In general, in .NET you can't know from whence your code has been called much beyond the function level by reflecting the callstack. The StackFrame object from [System.Diagnostics][1] will tell you the IL offset for the current method, so I suppose if you are really determined you could take apart the IL for the current method and try and figure out where you are within any try/finally code, but that's sounding really flimsy and gross to me.
What on earth are you trying to do that you feel you must manage it like this?
To me it feels like what you want is a factory object of some kind:
public interface IMyClass { int Level { get; } } // whatever
public class MyClassFactory {
private delegate void Notifier(int level);
public class MyClass : IDisposable
{
public MyClass(int level, Notifier notifier)
{
_level = level;
_notifier = notifier;
}
private int _level;
private Notifier _notifier;
~MyClass() { Dispose(false); }
public int Level { get { return level; } }
public Dispose() { Dispose(true); GC.SuppressFinalize(this); }
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed) {
if (disposing) {
notifier(Level);
_disposed = false;
}
else { throw new Exception("My class used outside using block."); }
}
}
}
private int _level = 0;
public IMyClass Make()
{
return new MyClass(_level++,
childLevel => {
if (childLevel == _level)
--_level;
else throw new Exception("Disposed out of order.");
});
}
}
What this does is build a factory that hides the constructor to MyClass and exposes a factory method to make IMyClass objects that you can use. It does a strict ordering such that objects are constructed and disposed in order, which more or less meets your nesting requirement. You can make the objects do something different based on their Level, if you so choose.
And I would still hesitate to use this code. It doesn't feel right, but at least it's harder to do something wrong as long as you only use one factory per method.
I'm guessing that what you really want to do is to have begin/end semantics in a code block that tracks nesting, but you want the compiler to manage that for you. That I've done with an object that takes two functions to call, one on begin and one on end:
public class BeginEnd<T> : IDisposable
{
private Action<T> _end;
private bool _disposed;
private T _val;
public BeginEnd(T val, Action<T> begin, Action<T> end)
{
_end = end;
_val = val;
begin(val);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
~BeginEnd() { Dispose(false); }
protected virtual void Dispose(bool disposing)
{
if (!_disposed) {
if (disposing) {
_disposed = true;
_end(_val);
}
}
}
}
Which can then be used in a context like this:
public class Tracker {
private int _level;
public BeginEnd<int> Track()
{
return new BeginEnd<int>(_level++,
lev1 => {
Debug.WriteLine("Begin " + lev1);
},
lev2 => {
Debug.WriteLine("End " + lev2);
--_level;
});
}
}
//...
Tracker t = new Tracker();
using (var n0 = t.Track()) {
using (var n1 = t.Track()) {
}
using (var n2 = t.Track()) { }
}
// prints:
// Begin 0
// Begin 1
// End 1
// Begin 1
// End 1
// End 0
which correctly tracks the nesting of the using blocks by enforcing a begin/end rule.
Whether or not this is an appropriate use of the language construct has been debated before. I feel like your problem can be solved in another more appropriate way.
When you use a ThreadLocal<T> and T implements IDisposable, how are you supposed to dispose of the members being held inside of the ThreadLocal?
According to ILSpy, the Dispose() and Dispose(bool) methods of ThreadLocal are
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
int currentInstanceIndex = this.m_currentInstanceIndex;
if (currentInstanceIndex > -1 && Interlocked.CompareExchange(ref this.m_currentInstanceIndex, -1, currentInstanceIndex) == currentInstanceIndex)
{
ThreadLocal<T>.s_availableIndices.Push(currentInstanceIndex);
}
this.m_holder = null;
}
It does not appear that ThreadLocal attempts to call Dispose on its child members. I can't tell how to reference each thread it internally has allocated so I can take care of it.
I ran a test with the following code, the class is never disposed
static class Sandbox
{
static void Main()
{
ThreadLocal<TestClass> test = new ThreadLocal<TestClass>();
test.Value = new TestClass();
test.Dispose();
Console.Read();
}
}
class TestClass : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool Disposing)
{
Console.Write("I was disposed!");
}
}
I had a look at the code in ThreadLocal<T> to see what the current Dispose is doing and it appears to be a lot of voodoo. Obviously disposing of thread-related stuff.
But it doesn't dispose of the values if T itself is disposable.
Now, I have a solution - a ThreadLocalDisposables<T> class, but before I give the full definition it's worth thinking about what should happen if you wrote this code:
var tl = new ThreadLocalDisposables<IExpensiveDisposableResource>();
tl.Value = myEdr1;
tl.Value = myEdr2;
tl.Dispose();
Should both myEdr1 & myEdr2 both be disposed? Or just myEdr2? Or should myEdr1 be disposed when myEdr2 was assigned?
It's not clear to me what the semantics should be.
It is clear to me, however, that if I wrote this code:
var tl = new ThreadLocalDisposables<IExpensiveDisposableResource>(
() => new ExpensiveDisposableResource());
tl.Value.DoSomething();
tl.Dispose();
Then I would expect that the resource created by the factory for each thread should be disposed of.
So I'm not going to allow the direct assignment of the disposable value for ThreadLocalDisposables and only allow the factory constructor.
Here's ThreadLocalDisposables:
public class ThreadLocalDisposables<T> : IDisposable
where T : IDisposable
{
private ThreadLocal<T> _threadLocal = null;
private ConcurrentBag<T> _values = new ConcurrentBag<T>();
public ThreadLocalDisposables(Func<T> valueFactory)
{
_threadLocal = new ThreadLocal<T>(() =>
{
var value = valueFactory();
_values.Add(value);
return value;
});
}
public void Dispose()
{
_threadLocal.Dispose();
Array.ForEach(_values.ToArray(), t => t.Dispose());
}
public override string ToString()
{
return _threadLocal.ToString();
}
public bool IsValueCreated
{
get { return _threadLocal.IsValueCreated; }
}
public T Value
{
get { return _threadLocal.Value; }
}
}
Does this help?
In .NET 4.5, the Values property was added to ThreadLocal<> to deal with the problem of manually managing the lifetime of ThreadLocal objects. It returns a list of all current instances bound to that ThreadLocal variable.
An example using a Parallel.For loop accessing a ThreadLocal database connection pool was presented in this MSDN article. The relevant code snippet is below.
var threadDbConn = new ThreadLocal<MyDbConnection>(() => MyDbConnection.Open(), true);
try
{
Parallel.For(0, 10000, i =>
{
var inputData = threadDbConn.Value.GetData(i);
...
});
}
finally
{
foreach(var dbConn in threadDbConn.Values)
{
dbConn.Close();
}
}
Normally when you don't explicitly dispose of a class that holds an unmanaged resource, the garbage collector will eventually run and dispose of it. For this to happen, the class has to have a finalizer that disposes of its resource. Your sample class doesn't have a finalizer.
Now, to dispose of a class that's held inside a ThreadLocal<T> where T is IDisposable you also have to do it yourself. ThreadLocal<T> is just a wrapper, it won't attempt to guess what's the correct behavior for its wrapped reference when it is itself disposed. The class could, e.g., survive its thread local storage.
This is related to ThreadLocal<> and memory leak
My guess is because there is no IDisposable constraint on T, it is assumed that the user of ThreadLocal<T> will dispose of the local object, when appropriate.
How is the ThreadLocal.Dispose method itself getting called? I would expect that it would most likely be within something like a "using" block. I would suggest that one wrap the "using" block for the ThreadLocal with a "using" block for the resource that's going to be stored there.
MSDN reference states that the ThreadLocal values should be disposed by the thread using them once its done. However in some instances such as event threading using a thread pool A thread may use the value and go off to do something else and then come back to the value N number of times.
Specific example is where I want an Entity Framework DBContext to persist across the lifespan of a series of service bus worker threads.
I've written up the following class which I use in these instances:
Either DisposeThreadCompletedValues can be called manually every so often by another thread or the internal monitor thread can be activated
Hopefully this helps?
using System.Threading;
public class DisposableThreadLocal<T> : IDisposable
where T : IDisposable
{
public DisposableThreadLocal(Func<T> _ValueFactory)
{
Initialize(_ValueFactory, false, 1);
}
public DisposableThreadLocal(Func<T> _ValueFactory, bool CreateLocalWatcherThread, int _CheckEverySeconds)
{
Initialize(_ValueFactory, CreateLocalWatcherThread, _CheckEverySeconds);
}
private void Initialize(Func<T> _ValueFactory, bool CreateLocalWatcherThread, int _CheckEverySeconds)
{
m_ValueFactory = _ValueFactory;
m_CheckEverySeconds = _CheckEverySeconds * 1000;
if (CreateLocalWatcherThread)
{
System.Threading.ThreadStart WatcherThreadStart;
WatcherThreadStart = new ThreadStart(InternalMonitor);
WatcherThread = new Thread(WatcherThreadStart);
WatcherThread.Start();
}
}
private object SyncRoot = new object();
private Func<T> m_ValueFactory;
public Func<T> ValueFactory
{
get
{
return m_ValueFactory;
}
}
private Dictionary<Thread, T> m_InternalDict = new Dictionary<Thread, T>();
private Dictionary<Thread, T> InternalDict
{
get
{
return m_InternalDict;
}
}
public T Value
{
get
{
T Result;
lock(SyncRoot)
{
if (!InternalDict.TryGetValue(Thread.CurrentThread,out Result))
{
Result = ValueFactory.Invoke();
InternalDict.Add(Thread.CurrentThread, Result);
}
}
return Result;
}
set
{
lock (SyncRoot)
{
if (InternalDict.ContainsKey(Thread.CurrentThread))
{
InternalDict[Thread.CurrentThread] = value;
}
else
{
InternalDict.Add(Thread.CurrentThread, value);
}
}
}
}
public bool IsValueCreated
{
get
{
lock (SyncRoot)
{
return InternalDict.ContainsKey(Thread.CurrentThread);
}
}
}
public void DisposeThreadCompletedValues()
{
lock (SyncRoot)
{
List<Thread> CompletedThreads;
CompletedThreads = new List<Thread>();
foreach (Thread ThreadInstance in InternalDict.Keys)
{
if (!ThreadInstance.IsAlive)
{
CompletedThreads.Add(ThreadInstance);
}
}
foreach (Thread ThreadInstance in CompletedThreads)
{
InternalDict[ThreadInstance].Dispose();
InternalDict.Remove(ThreadInstance);
}
}
}
private int m_CheckEverySeconds;
private int CheckEverySeconds
{
get
{
return m_CheckEverySeconds;
}
}
private Thread WatcherThread;
private void InternalMonitor()
{
while (!IsDisposed)
{
System.Threading.Thread.Sleep(CheckEverySeconds);
DisposeThreadCompletedValues();
}
}
private bool IsDisposed = false;
public void Dispose()
{
if (!IsDisposed)
{
IsDisposed = true;
DoDispose();
}
}
private void DoDispose()
{
if (WatcherThread != null)
{
WatcherThread.Abort();
}
//InternalDict.Values.ToList().ForEach(Value => Value.Dispose());
foreach (T Value in InternalDict.Values)
{
Value.Dispose();
}
InternalDict.Clear();
m_InternalDict = null;
m_ValueFactory = null;
GC.SuppressFinalize(this);
}
}