对静态类的公共静态队列的引用会丢失

时间:2017-04-21 19:03:17

标签: c# static static-methods

我有一个静态类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.");
        }
    }       
}

0 个答案:

没有答案