Skip to content

Instantly share code, notes, and snippets.

@mirasrael
Last active November 2, 2018 06:03
Show Gist options
  • Save mirasrael/0c1481e1fce1317466a9b4b23f02ecd8 to your computer and use it in GitHub Desktop.
Save mirasrael/0c1481e1fce1317466a9b4b23f02ecd8 to your computer and use it in GitHub Desktop.
Stream with lock released on Dispose
using System.IO;
using System.Threading;
/// <summary>
/// This Stream used in cases when we need only synchronized access to some objects, but these objects provides Stream to external consumers for read or write.
/// Then the stream can just be wrapped in this LockStream, it will automatically obtain lock in constructor and will release it only on Dispose.
///
/// WARNING: For external consumers ensure you closed this stream!
/// </summary>
public class LockStream : Stream
{
private readonly object syncRoot;
private readonly Stream monitoredStream;
public LockStream(Stream monitoredStream, object syncRoot)
{
this.monitoredStream = monitoredStream;
this.syncRoot = syncRoot;
Monitor.Enter(syncRoot);
}
public override bool CanRead => this.monitoredStream.CanRead;
public override bool CanSeek => this.monitoredStream.CanSeek;
public override bool CanWrite => this.monitoredStream.CanWrite;
public override long Length => this.monitoredStream.Length;
public override bool CanTimeout => this.monitoredStream.CanTimeout;
public override int ReadTimeout
{
get => this.monitoredStream.ReadTimeout;
set => this.monitoredStream.ReadTimeout = value;
}
public override int WriteTimeout
{
get => this.monitoredStream.WriteTimeout;
set => this.monitoredStream.WriteTimeout = value;
}
public override long Position
{
get => this.monitoredStream.Position;
set => this.monitoredStream.Position = value;
}
public override void Flush() => this.monitoredStream.Flush();
public override long Seek(long offset, SeekOrigin origin) => this.monitoredStream.Seek(offset, origin);
public override void SetLength(long value) => this.monitoredStream.SetLength(value);
public override int Read(byte[] buffer, int offset, int count) => this.monitoredStream.Read(buffer, offset, count);
public override void Write(byte[] buffer, int offset, int count) => this.monitoredStream.Write(buffer, offset, count);
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
this.monitoredStream.Dispose();
}
finally
{
try
{
Monitor.Exit(this.syncRoot);
}
finally
{
base.Dispose(disposing);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment