check point
This commit is contained in:
48
framework/Inspectron.Statistics/CsvStatistics.cs
Normal file
48
framework/Inspectron.Statistics/CsvStatistics.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Globalization;
|
||||
using CsvHelper;
|
||||
|
||||
namespace Inspectron.Statistics;
|
||||
|
||||
public class CsvStatistics
|
||||
{
|
||||
private readonly string _filePath;
|
||||
private readonly StreamWriter _stream;
|
||||
private readonly FileStream _fileStream;
|
||||
private readonly CsvWriter _csv;
|
||||
|
||||
public CsvStatistics(string filePath, string[] headers)
|
||||
{
|
||||
_filePath = filePath;
|
||||
var newFile = !File.Exists(filePath);
|
||||
_fileStream = File.Open(_filePath, FileMode.Append);
|
||||
_stream = new StreamWriter(_fileStream);
|
||||
_csv = new CsvWriter(_stream,CultureInfo.InvariantCulture);
|
||||
if (newFile)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
_csv.WriteField(header);
|
||||
}
|
||||
_csv.NextRecord();
|
||||
_csv.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLine(string[] values)
|
||||
{
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
_csv.WriteField(values[i]);
|
||||
}
|
||||
_csv.NextRecord();
|
||||
_csv.Flush();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_csv.Dispose();
|
||||
_stream.Dispose();
|
||||
_fileStream.Dispose();
|
||||
|
||||
}
|
||||
}
|
||||
6
framework/Inspectron.Statistics/IStatistics.cs
Normal file
6
framework/Inspectron.Statistics/IStatistics.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Inspectron.Statistics;
|
||||
|
||||
public interface IStatistics:IDisposable
|
||||
{
|
||||
void WriteLine(StatisticsRecord record);
|
||||
}
|
||||
13
framework/Inspectron.Statistics/Inspectron.Statistics.csproj
Normal file
13
framework/Inspectron.Statistics/Inspectron.Statistics.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="27.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
92
framework/Inspectron.Statistics/LockedCsvStatistics.cs
Normal file
92
framework/Inspectron.Statistics/LockedCsvStatistics.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Globalization;
|
||||
using CsvHelper;
|
||||
|
||||
namespace Inspectron.Statistics;
|
||||
|
||||
public class LockedCsvStatistics : IStatistics
|
||||
{
|
||||
private readonly string _filePath;
|
||||
private readonly string _lockFilePath;
|
||||
private readonly string[] _headers;
|
||||
|
||||
public LockedCsvStatistics(string filePath, string[] headers)
|
||||
{
|
||||
_filePath = filePath;
|
||||
_lockFilePath = filePath + ".lock";
|
||||
_headers = headers;
|
||||
|
||||
var directoryPath = Path.GetDirectoryName(filePath);
|
||||
if (directoryPath != null && !Directory.Exists(directoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLine(StatisticsRecord record)
|
||||
{
|
||||
AcquireLock();
|
||||
|
||||
try
|
||||
{
|
||||
bool writeHeaders = !File.Exists(_filePath) || new FileInfo(_filePath).Length == 0;
|
||||
|
||||
using var fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.None);
|
||||
using var streamWriter = new StreamWriter(fileStream);
|
||||
using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
|
||||
|
||||
if (writeHeaders)
|
||||
{
|
||||
foreach (var header in _headers)
|
||||
{
|
||||
csvWriter.WriteField(header);
|
||||
}
|
||||
csvWriter.NextRecord();
|
||||
csvWriter.Flush();
|
||||
}
|
||||
|
||||
foreach (var value in record.Values)
|
||||
{
|
||||
csvWriter.WriteField(value);
|
||||
}
|
||||
csvWriter.NextRecord();
|
||||
csvWriter.Flush();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// No resources to dispose
|
||||
}
|
||||
|
||||
private void AcquireLock()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (File.Open(_lockFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
||||
{
|
||||
// Lock acquired
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Lock file already exists, wait and retry
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseLock()
|
||||
{
|
||||
if (File.Exists(_lockFilePath))
|
||||
{
|
||||
File.Delete(_lockFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
framework/Inspectron.Statistics/StatisticsRecord.cs
Normal file
6
framework/Inspectron.Statistics/StatisticsRecord.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Inspectron.Statistics;
|
||||
|
||||
public class StatisticsRecord
|
||||
{
|
||||
public string[] Values { get; set; }
|
||||
}
|
||||
64
framework/Inspectron.Statistics/StatisticsWritter.cs
Normal file
64
framework/Inspectron.Statistics/StatisticsWritter.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Inspectron.Statistics;
|
||||
|
||||
public class StatisticsWritter:IStatistics
|
||||
{
|
||||
private readonly Func<IStatistics> _statisticsBuilder;
|
||||
|
||||
private bool _running = true;
|
||||
public StatisticsWritter(Func<IStatistics> statisticsBuilder)
|
||||
{
|
||||
_statisticsBuilder = statisticsBuilder;
|
||||
Thread th = new Thread(WritingLoop);
|
||||
th.IsBackground = false;
|
||||
th.Start();
|
||||
}
|
||||
|
||||
private void WritingLoop()
|
||||
{
|
||||
while (_running)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var statistics = _statisticsBuilder())
|
||||
{
|
||||
while (_recordQueue.TryDequeue(out var res))
|
||||
{
|
||||
var error = false;
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
statistics.WriteLine(res);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = true;
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
} while (error);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
|
||||
private ConcurrentQueue<StatisticsRecord> _recordQueue = new ConcurrentQueue<StatisticsRecord>();
|
||||
public void WriteLine(StatisticsRecord record)
|
||||
{
|
||||
_recordQueue.Enqueue(record);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user