|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.ComponentModel.Design
{
/// <summary>
/// Identifies a transaction within a designer. Transactions are
/// used to wrap several changes into one unit of work, which
/// helps performance.
/// </summary>
public abstract class DesignerTransaction : IDisposable
{
private bool _suppressedFinalization;
protected DesignerTransaction() : this("")
{
}
protected DesignerTransaction(string description) => Description = description;
public bool Canceled { get; private set; }
public bool Committed { get; private set; }
public string Description { get; }
public void Cancel()
{
if (!Canceled && !Committed)
{
Canceled = true;
GC.SuppressFinalize(this);
_suppressedFinalization = true;
OnCancel();
}
}
/// <summary>
/// Commits this transaction. Once a transaction has been committed, further
/// calls to this method will do nothing. You should always call this method
/// after creating a transaction to ensure that the transaction is closed properly.
/// </summary>
public void Commit()
{
if (!Committed && !Canceled)
{
Committed = true;
GC.SuppressFinalize(this);
_suppressedFinalization = true;
OnCommit();
}
}
/// <summary>
/// User code should implement this method to perform the actual work of
/// committing a transaction.
/// </summary>
protected abstract void OnCancel();
/// <summary>
/// User code should implement this method to perform the actual work of
/// committing a transaction.
/// </summary>
protected abstract void OnCommit();
/// <summary>
/// Overrides Object to commit this transaction in case the user forgot.
/// </summary>
~DesignerTransaction() => Dispose(false);
/// <summary>
/// Private implementation of IDisaposable. When a transaction is disposed
/// it is committed.
/// </summary>
void IDisposable.Dispose()
{
Dispose(true);
if (!_suppressedFinalization)
{
GC.SuppressFinalize(this);
}
}
protected virtual void Dispose(bool disposing) => Cancel();
}
}
|