init
This commit is contained in:
166
Common/DTS.CommonCore/Utils/SecureQueue.cs
Normal file
166
Common/DTS.CommonCore/Utils/SecureQueue.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.Common.Utils
|
||||
{
|
||||
public class SecureQueue<T> : IDisposable where T : new()
|
||||
{
|
||||
public enum NullPolicy
|
||||
{
|
||||
DenyNull, // throw an exception if try to Enqueue null or zero length
|
||||
SkipNull, // don't complain but don't enqueue null or zero length
|
||||
AllowNull // let null's in too
|
||||
}
|
||||
|
||||
protected Queue<T[]> ByteQueue;
|
||||
protected object ByteQueueLock;
|
||||
protected ManualResetEvent ByteQueueEvent;
|
||||
protected NullPolicy _NullPolicy;
|
||||
protected string Name;
|
||||
protected Stopwatch StopWatch;
|
||||
|
||||
public SecureQueue(NullPolicy policy, string name)
|
||||
{
|
||||
StopWatch = new Stopwatch();
|
||||
StopWatch.Start();
|
||||
ByteQueue = new Queue<T[]>();
|
||||
ByteQueueLock = new object();
|
||||
ByteQueueEvent = new ManualResetEvent(false);
|
||||
_NullPolicy = policy;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public void ResetEvent()
|
||||
{
|
||||
//latestReset = GetCaller();
|
||||
ByteQueueEvent.Reset();
|
||||
}
|
||||
|
||||
public void Enqueue(T[] newData)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (ByteQueueLock)
|
||||
{
|
||||
if (newData == null || newData.Length == 0)
|
||||
{
|
||||
switch (_NullPolicy)
|
||||
{
|
||||
case NullPolicy.DenyNull:
|
||||
throw new ArgumentException("SecureQueue_Enqueue_Err1");
|
||||
case NullPolicy.SkipNull:
|
||||
return;
|
||||
}
|
||||
}
|
||||
ByteQueue.Enqueue((T[])newData?.Clone());
|
||||
if (Enums.DASFactory.DFConstantsAndEnums.ExtraCommunicationLogging)
|
||||
{
|
||||
APILogger.Log("Enqueing data", newData);
|
||||
}
|
||||
ByteQueueEvent.Set();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogString("SecureQueue.Enqueue: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wait for TimeoutMillisec milliseconds for data to arrive in the buffer. Returns false if it times out.
|
||||
/// </summary>
|
||||
/// <param name="timeoutMillisec"></param>
|
||||
/// <returns>true if data has arrived, false if it times out</returns>
|
||||
public bool WaitForData(int timeoutMillisec)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = ByteQueueEvent.WaitOne(timeoutMillisec, false);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogString("SecureQueue.WaitForData: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public WaitHandle QueueWaitHandle => ByteQueueEvent;
|
||||
|
||||
public T[] Dequeue(bool resetEvent)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (ByteQueueLock)
|
||||
{
|
||||
ByteQueueEvent = new ManualResetEvent(false);
|
||||
|
||||
if (ByteQueue.Count == 0)
|
||||
{
|
||||
return new T[0];
|
||||
}
|
||||
if (ByteQueue.Count == 1)
|
||||
{
|
||||
var ret = ByteQueue.Dequeue();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// count how much data we have
|
||||
var totalBytes = ByteQueue.Sum(arr => arr.Length);
|
||||
if (totalBytes == 0)
|
||||
{
|
||||
APILogger.LogString("SecureQueue.Dequeue: The queue(" + Name + ") has 0 bytes!");
|
||||
}
|
||||
// allocate that much
|
||||
var result = new T[totalBytes];
|
||||
var index = 0;
|
||||
// now make one large array
|
||||
while (ByteQueue.Any())
|
||||
{
|
||||
var element = ByteQueue.Dequeue();
|
||||
Array.Copy(element, 0, result, index, element.Length);
|
||||
index += element.Length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogString("SecureQueue.Dequeue: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
||||
}
|
||||
return new T[0];
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (ByteQueueLock)
|
||||
{
|
||||
//latestFlush = GetCaller();
|
||||
ByteQueueEvent = new ManualResetEvent(false);
|
||||
ByteQueue.Clear();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogString("SecureQueue.Flush: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return ByteQueue.Count == 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user