0

I have a strange problem with following code, that is started about every minute. Normally everything works fine, but sometimes the HandleCalcStatistikMarkersDone function raises an error because of a NullReferenceException.

I try to explain with the code:

I have a class Strategies. This class is started about every minute to calculate and update some information in a MySQL database. This class is instantiated multiple times in separate threads within a ticker on a form.

public partial class mainForm: Form
{
//do something including ticker, that starts RunStatistik about every minute after the previous thread ended

   private void RunStatistik()
    {            
        foreach (InternalObject objPar in InternalObjects)
        {
            Strategies.StrategyParameter giveParms = new Strategies.StrategyParameter();
            giveParms.pair= objPar.pair;

            Strategies strat = new Strategies();
            Thread calcStatistikThread = new Thread(new ParameterizedThreadStart(strat.CalcCoinStatistik));
            calcStatistikThread.Start(giveParms);

        }
    }
}

Internally in the upper initiated Strategies thread, there are stared some additional threads. Those threads have a "DoneEvent" which is raised at the end of the function.

To notice, that all threads have ended before the main thread ends, I collect all subthreads in a List CalcStatistikMarkersThreads and wait until the list is empty. The subthreads should remove themselves out of the upper List via the ThreadDone event. But sometimes the searched thread (CalcStatistikMarkersThreads.Find) is not found anymore and I get a NullReferenceException. The question is why?!

Could you tell me, why? And possibly how to prevent?

Thanks in advance.

class Strategies
{   public event EventHandler ThreadDone;
    private List<Thread> CalcStatistikMarkersThreads;

//do something

    public void CalcCoinStatistik(object parameters)
    {
    StrategyParameter givenParms = (StrategyParameter)parameters;
    Pair internalPair = givenParms.pair

    //do something

        if (CalcStatistikMarkersThreads == null)
        {
            CalcStatistikMarkersThreads = new List<Thread>();
        }

        foreach (InternalTodo in InternalToDos)
        {
            Strategies strat = new Strategies();
            CalcStatistikMarkersParameter csp = new CalcStatistikMarkersParameter();
            csp.parm1 = param;

            strat.ThreadDone += HandleCalcStatistikMarkersDone;

            Thread candleCalc = new Thread(new ParameterizedThreadStart(strat.CalcStatistikMarkers));

            CalcStatistikMarkersThreads.Add(candleCalc);
            candleCalc.Start(csp);

            while (CalcStatistikMarkersThreads.Count != 0)
            {                   
                Task.Delay(1000).Wait();                    
            }                 
        }        
    }

    public void CalcStatistikMarkers(object parm)
    {
    //do something      

        if (ThreadDone != null)
            ThreadDone(this, new ThreadInfoEventArgs(Thread.CurrentThread.ManagedThreadId));
    }

    public void HandleCalcStatistikMarkersDone(object sender, EventArgs e)
    {
        Guid workGUID = Guid.NewGuid();
        ThreadInfoEventArgs tEv = (ThreadInfoEventArgs)e;
        Thread currentThread;

        try
        {
            currentThread = CalcStatistikMarkersThreads.Find(xy => xy.ManagedThreadId == tEv.ThreadID);
            //HERE THE NullReferenceException is raised sometimes
            CalcStatistikMarkersThreads.Remove(currentThread);
        }
        catch (Exception ex)
        {
            throw ex;
        }            
    }


    public class ThreadInfoEventArgs : EventArgs
    {
        private int threadID;
        public ThreadInfoEventArgs(int trID)
        {
            this.threadID = trID;
        }
        public int ThreadID
        {
            get { return threadID; }
        }
    }

}

Cheers Air

Partha
  • 402
  • 4
  • 15
Airwave
  • 136
  • 4
  • 15
  • I am assuming handling exception with try catch will not help, as you want the cause of problem to be solved not just handle the scene. If you debug on problematic cases `CalcStatistikMarkersThreads` is entirely empty or just not contains particular thread only? – Amit Jun 01 '18 at 10:06
  • It's a little problem to debug this with visual studio. I only have the problem in the production system. I logged a .Count on the CalcStatistikMarkersThreads. It showes, that the variable is filled with the correct number. When I then try to iterate thourgh the threads via for each thread in CalcStatistikMarkersThreads then it throws also a NullReferenceException – Airwave Jun 01 '18 at 13:16

0 Answers0