我有一个静态类A,它有一个公共静态ConcurrentQueue。 这个类有一个方法,它调用另一个静态类B的方法。
在这个静态类B的方法中,启动一个工作线程,它会轮询A类的静态ConcurrentQueue中的项目。如果找到,它会使项目出列并对其进行处理。
B类中的相同方法也会启动另一个线程,该线程检查A类队列是否经常被填充。如果填充偶尔会卡住,则会调用A类中的静态方法,该方法会重置并重新启动该过程。
问题出现了:当我重新启动填充时,项目再次插入到静态类A的静态队列中。但我在静态类B中检查队列中的项目的线程不再找到任何项目。
所以我的想法是,在B类中,我不知何故丢失了对A类原始静态队列的引用。我想我在这里监督静态类的一些原则,但无法弄清楚到底是什么。
编辑:这里有更多细节。
主:
public static void Main(string[] args)
{
B.Initialize(8);
A.StartDataStream();
Console.ReadKey();
}
A类:
class A
{
private static ACOMObject MyCOMObjekt;
public static ConcurrentQueue<PriceItem> Prices = new ConcurrentQueue<PriceItem>();
public static void StartDataStream()
{
DataStream myDataStream = GetDataStream();
FillStream(myDataStream);
B.StartHeartbeatCheck();
Console.WriteLine("Press Key to Exit Stream Call.");
Console.ReadKey();
GC.KeepAlive(myDataStream);
GC.KeepAlive(MyCOMObjekt);
}
private static DataStream GetDataStream()
{
if (MyCOMObjekt== null)
{
MyCOMObjekt= new ACOMObject ();
}
return (DataStream) MyCOMObjekt.DataStream;
}
private static void FillStream(DataStream myDataStream)
{
foreach (var symbol in Symbols.SymbolList)
{
myDataStream.Add(symbolNr, 1);
}
myDataStream.Bid += new _IDataStreamEvents_BidEventHandler(myDataStream_Bid);
myDataStream.Ask += new _IDataStreamEvents_AskEventHandler(myDataStream_Ask);
}
private static void myDataStream_Bid(int SymbolNr, float Price, DateTime Time)
{
PriceItem p;
p.SymbolNr = SymbolNr;
p.Price = Price;
p.Time = Time;
p.IsBid = true;
Prices.Enqueue(p);
}
private static void myDataStream_Ask(int SymbolNr, float Price, DateTime Time)
{
PriceItem p;
p.SymbolNr = SymbolNr;
p.Price = Kurs;
p.Time = Zeit;
p.IsBid = false;
Prices.Enqueue(p);
}
public static void RestartMyCOMProcess()
{
try
{
Process proc = Process.GetProcessesByName("MyCOMProcess")[0];
proc.Kill();
}
catch (Exception)
{
//No Process = fine
}
MyCOMObjekt = null;
DataStream myDataStream = GetDataStream();
myDataStream.Bid -= new _IDataStreamEvents_BidEventHandler(myDataStream_Bid); //probably not necessary...
myDataStream.Ask -= new _IDataStreamEvents_AskEventHandler(myDataStream_Ask); //probably not necessary...
FillStream(myDataStream);
}
}
B组:
class B
{
private static int countPrices; //Incremented every time a price is taken out of Price Queue
public static void Initialize(int numberOfWorkerThreads)
{
StartWorkers(numberOfWorkerThreads);
}
public static void StartWorkers(int number)
{
for (int j = 0; j < number; j++)
{
Thread t = new Thread(ScanForPrices);
t.Name = "ScanForPrices" + j;
t.Start();
}
}
private static void ScanForPrices()
{
try
{
while (true)
{
PriceItem p;
if (A.Prices.TryDequeue(out p))
{
if (p.IsBid)
{
AnalyzeBidPrice(p);
}
else
{
HandleAskPrice(p);
}
Interlocked.Increment(ref countPrices)
}
else
{
Thread.Sleep(1);
}
}
}
catch (ThreadAbortException)
{
Console.WriteLine("Price Scan Thread aborted.");
}
}
public static void StartHeartbeatCheck()
{
Thread t = new Thread(CheckHeartBeat);
t.Name = "CheckHeartBeat";
t.Start();
}
private static void CheckHeartBeat()
{
TimeSpan start = new TimeSpan(09, 0, 0); //09 o'clock
TimeSpan end = new TimeSpan(20, 0, 0); //20 o'clock
TimeSpan stopTime = new TimeSpan(20, 5, 0); //20 o'clock and 5 minutes
int countSuccessiveBlockings = 0;
try
{
while (true)
{
Thread.Sleep(5000);
TimeSpan now = DateTime.Now.TimeOfDay;
if ((now > start) && (now < end))
{
int countOld = countPrices;
Thread.Sleep(1000);
if (countOld == countPrices)
{
Console.WriteLine(DateTime.Now + ": Price Stream blocked!");
countSuccessiveBlockings++;
}
else
{
countSuccessiveBlockings = 0;
}
if (countSuccessiveBlockings > 2)
{
A.RestartMyCOMProcess();
countSuccessiveBlockings = 0;
}
}
}
}
catch (ThreadAbortException)
{
Console.WriteLine("Heartbeat Thread aborted.");
}
}
}