using System; using System.Collections.Concurrent; using System.Threading.Tasks; using ZeroLevel.Network.FileTransfer; namespace ZeroLevel.Services.Network.FileTransfer.Writers { internal sealed class SafeDataWriter : IDisposable { private readonly IDataWriter _writer; private readonly Action _complete; private BlockingCollection _chunks = new BlockingCollection(); private volatile bool _disposed = false; public SafeDataWriter(IDataWriter writer, Action complete) { _writer = writer; _complete = complete; Task.Run(() => { try { FileFrame frame; while (!_chunks.IsCompleted) { if (_chunks.TryTake(out frame, 200)) { writer.Write(frame.Offset, frame.Payload); } } _writer.CompleteReceiving(); _complete?.Invoke(); } catch (Exception ex) { Log.Error(ex, "[SafeDataWriter.ctor receive loop] Fault receive data"); } }); } public void CompleteReceiving() { Sheduller.RemindAfter(TimeSpan.FromSeconds(1), _chunks.CompleteAdding); } public void Dispose() { _disposed = true; _chunks.Dispose(); _writer.Dispose(); } public bool IsTimeoutBy(TimeSpan period) => _writer.IsTimeoutBy(period); public void Write(FileFrame frame) { if (!_disposed) { _chunks.Add(frame); } } } }