Last active
November 2, 2018 06:03
-
-
Save mirasrael/0c1481e1fce1317466a9b4b23f02ecd8 to your computer and use it in GitHub Desktop.
Stream with lock released on Dispose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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