एक ताला के बिंदु के बाद से में रक्षा के लिए है स्मृति का कुछ टुकड़ा, मुझे लगता है कि उस स्मृति को "लॉक" ऑब्जेक्ट में लपेटना उपयोगी होगा, और केवल इसे विभिन्न लॉक टोकन के माध्यम से एक्सेस करें (जैसा कि Mark द्वारा उल्लिखित है):
// Stores a private List<T>, only accessible through lock tokens
// returned by Read, Write, and UpgradableRead.
var lockedList = new LockedList<T>();
using(var r = lockedList.Read()) {
foreach(T item in r.Reader)
...
}
using(var w = lockedList.Write()) {
w.Writer.Add(new T());
}
T t = ...;
using(var u = lockedList.UpgradableRead()) {
if(!u.Reader.Contains(t))
using(var w = u.Upgrade())
w.Writer.Add(t);
}
अब आंतरिक सूची का उपयोग करने के लिए एक ही रास्ता उचित एक्सेसर फोन करके है।
यह List<T>
के लिए विशेष रूप से अच्छी तरह से काम करता है, क्योंकि इसमें पहले से ही ReadOnlyCollection<T>
रैपर है। अन्य प्रकार के लिए, आप हमेशा Locked<T,T>
बना सकते हैं, लेकिन फिर आप अच्छे पठनीय/लिखने योग्य प्रकार भेद पर हार जाते हैं।
ही एक सुधार के लिए खुद को डिस्पोजेबल रैपर के रूप में R
और W
प्रकार, जो (inadvertant) त्रुटियों के खिलाफ की तरह संरक्षित हैं परिभाषित करने के लिए हो सकता है:
List<T> list;
using(var w = lockedList.Write())
list = w.Writable;
//BAD: "locked" object leaked outside of lock scope
list.MakeChangesWithoutHoldingLock();
हालांकि, इस Locked
अधिक उपयोग करने के लिए जटिल बना होता है, और मौजूदा संस्करण आपको एक ही सुरक्षा प्रदान करता है जब आपके द्वारा साझा किए गए सदस्य को मैन्युअल रूप से लॉक करते समय।
sealed class LockedList<T> : Locked<List<T>, ReadOnlyCollection<T>> {
public LockedList()
: base(new List<T>(), list => list.AsReadOnly())
{ }
}
public class Locked<W, R> where W : class where R : class {
private readonly LockerState state_;
public Locked(W writer, R reader) { this.state_ = new LockerState(reader, writer); }
public Locked(W writer, Func<W, R> getReader) : this(writer, getReader(writer)) { }
public IReadable Read() { return new Readable(this.state_); }
public IWritable Write() { return new Writable(this.state_); }
public IUpgradable UpgradableRead() { return new Upgradable(this.state_); }
public interface IReadable : IDisposable { R Reader { get; } }
public interface IWritable : IDisposable { W Writer { get; } }
public interface IUpgradable : IReadable { IWritable Upgrade();}
#region Private Implementation Details
sealed class LockerState {
public readonly R Reader;
public readonly W Writer;
public readonly ReaderWriterLockSlim Sync;
public LockerState(R reader, W writer) {
Debug.Assert(reader != null && writer != null);
this.Reader = reader;
this.Writer = writer;
this.Sync = new ReaderWriterLockSlim();
}
}
abstract class Accessor : IDisposable {
private LockerState state_;
protected LockerState State { get { return this.state_; } }
protected Accessor(LockerState state) {
Debug.Assert(state != null);
this.Acquire(state.Sync);
this.state_ = state;
}
protected abstract void Acquire(ReaderWriterLockSlim sync);
protected abstract void Release(ReaderWriterLockSlim sync);
public void Dispose() {
if(this.state_ != null) {
var sync = this.state_.Sync;
this.state_ = null;
this.Release(sync);
}
}
}
class Readable : Accessor, IReadable {
public Readable(LockerState state) : base(state) { }
public R Reader { get { return this.State.Reader; } }
protected override void Acquire(ReaderWriterLockSlim sync) { sync.EnterReadLock(); }
protected override void Release(ReaderWriterLockSlim sync) { sync.ExitReadLock(); }
}
sealed class Writable : Accessor, IWritable {
public Writable(LockerState state) : base(state) { }
public W Writer { get { return this.State.Writer; } }
protected override void Acquire(ReaderWriterLockSlim sync) { sync.EnterWriteLock(); }
protected override void Release(ReaderWriterLockSlim sync) { sync.ExitWriteLock(); }
}
sealed class Upgradable : Readable, IUpgradable {
public Upgradable(LockerState state) : base(state) { }
public IWritable Upgrade() { return new Writable(this.State); }
protected override void Acquire(ReaderWriterLockSlim sync) { sync.EnterUpgradeableReadLock(); }
protected override void Release(ReaderWriterLockSlim sync) { sync.ExitUpgradeableReadLock(); }
}
#endregion
}
+1 महान स्निपेट! –
मजेदार, मैं इस बारे में भूल गया था और बस मौके से यह मेरी प्रतिष्ठा के अंक में खुलता है जैसे कि मैं इससे लाभ उठा सकता हूं। –