mirror of https://github.com/ogoun/Zero.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.8 KiB
66 lines
1.8 KiB
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<FileFrame> _chunks = new
|
|
BlockingCollection<FileFrame>();
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|