public interface ITransaction : IDisposable
{
void AddObjectToDispose(IDisposable disposableObject);
void Abort();
void Commit();
DBObject GetObject(ObjectId id, OpenMode mode);
DBObject GetObject(ObjectId id, OpenMode mode, bool openErased);
DBObject GetObject(ObjectId id, OpenMode mode, bool openErased, bool forceOpenOnLockedLayer);
T CreateNew
<T
>() where T
: DBObject,
new(); }
public class RollYourOwnTransaction : ITransaction
{
Queue
<IDisposable
> disposables
= new Queue
<IDisposable
>(); Queue
<DBObject
> dbobjectsDisposables
= new Queue
<DBObject
>();
private bool isDisposed = false;
public RollYourOwnTransaction()
{
}
~RollYourOwnTransaction()
{
this.Dispose(false);
}
public void AddObjectToDispose(IDisposable item)
{
disposables.Enqueue(item);
}
public void Abort()
{
this.Dispose(false);
GC.SuppressFinalize(this);
}
public void Commit()
{
this.Dispose();
}
public DBObject GetObject(ObjectId id, OpenMode mode)
{
DBObject obj = id.Open(mode, false, false);
dbobjectsDisposables.Enqueue(obj);
return obj;
}
public DBObject GetObject(ObjectId id)
{
DBObject obj = id.Open(OpenMode.ForRead, false, false);
dbobjectsDisposables.Enqueue(obj);
return obj;
}
public DBObject GetObject(ObjectId id, OpenMode mode, bool openErased)
{
DBObject obj = id.Open(mode, openErased, false);
dbobjectsDisposables.Enqueue(obj);
return obj;
}
public DBObject GetObject(ObjectId id, OpenMode mode, bool openErased, bool forceOpenOnLockedLayer)
{
DBObject obj = id.Open(mode, openErased, forceOpenOnLockedLayer);
dbobjectsDisposables.Enqueue(obj);
return obj;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
closeDbObjectQueue();
}
else
{
abortDBObjectQueue();
}
disposeQueue();
}
isDisposed = true;
}
void disposeQueue()
{
while (disposables.Count > 0)
{
disposables.Dequeue().Dispose();
}
disposables = null;
}
void closeDbObjectQueue()
{
while (dbobjectsDisposables.Count > 0)
{
if (dbobjectsDisposables.Peek().ObjectId.IsNull)
{
dbobjectsDisposables.Dequeue().Dispose();
}
else
{
dbobjectsDisposables.Dequeue().Close();
}
}
dbobjectsDisposables = null;
}
void abortDBObjectQueue()
{
while (dbobjectsDisposables.Count > 0)
{
if (dbobjectsDisposables.Peek().ObjectId.IsNull)
{
dbobjectsDisposables.Dequeue().Dispose();
}
else
{
dbobjectsDisposables.Dequeue().Cancel();
}
}
dbobjectsDisposables = null;
}
public T CreateNew
<T
>() where T
: DBObject,
new() {
dbobjectsDisposables.Enqueue(obj);
return obj;
}
}
public static class Extensions
{
public static ITransaction StartRollYourOwnTransaction(this Database db)
{
return new RollYourOwnTransaction
(); }
}