An interface for the beginning and the ending of the scope block #8420
Replies: 3 comments 1 reply
-
You may execute the logic you need in the constructor of |
Beta Was this translation helpful? Give feedback.
-
No no no, not in the constructor. If I do it in the constructor, then I can't control if something happens inside a using-block or not. e.g. I want to automatically rw-lock a class instance, once it enters a using block. If you do it simply in the constructor, you can't differentiate between the two use-cases. Concrete example: the ReaderWriterLockSlim when caching data, as in public CacheAccessor<CacheData> EntireCache
{
get
{
this.m_rwLock.EnterReadLock(); // This should only be done in the using clause of the code accessing EntireCache
// when it's not used in using statement (or with no lock manually taken), i want to make lookups of CacheData
// throw an error, like invalid operation - cannot access properties without having a rw-lock.
try
{
CacheAccessor<CacheData> cd = new CacheAccessor<CacheData>(this.m_cachedData, this.m_rwLock);
return cd;
} // End Try
catch (System.Exception ex)
{
this.m_rwLock.ExitReadLock();
throw;
}
} // End Getter
} // End Property EntireCache What I want is to not take a lock in the constructor, but a lock if the accessor is accessed inside a using statement: namespace CSharp.LanguageProposal.SealedUnsealed
{
public interface IEnterScope
{
void EnterScope();
}
public class CacheAccessor<T>
: System.IDisposable, IEnterScope
{
private readonly T m_cache;
private readonly System.Threading.ReaderWriterLockSlim m_rwLock;
private bool m_readlockTaken;
public CacheAccessor(T cacheData, System.Threading.ReaderWriterLockSlim rwLock)
{
this.m_cache = cacheData;
this.m_rwLock = rwLock; ;
this.m_readlockTaken = false; ;
} // End Constructor
public T Data
{
get
{
if (!m_readlockTaken)
throw new System.InvalidOperationException("You cannot access the cache-data without read-lock.");
return this.m_cache;
}
} // End Property Data
void System.IDisposable.Dispose()
{
this.ExitReadLock();
} // End Interface IDisposable.Dispose
void IEnterScope.EnterScope()
{
this.TakeReadlock();
} // End Interface IEnterScope.EnterScope
public void TakeReadlock()
{
this.m_rwLock.EnterReadLock();
this.m_readlockTaken = true;
} // End Sub TakeReadlock
public void ExitReadLock()
{
this.m_readlockTaken = false;
this.m_rwLock.ExitReadLock();
} // End Sub ExitReadLock
} // End Class CacheAccessor<T>
} // End Namespace |
Beta Was this translation helpful? Give feedback.
-
You can add an analyzer that warns or even produces an error if EnterReadLock() is not called with a using statement |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Create an Interface like IDisposable and IAsyncDisposable, but for the beginning of a using-scope.
Here is what i mean (IEnterScope, IEnterScopeAsync ):
Beta Was this translation helpful? Give feedback.
All reactions