C#对象引用在通过EventHandler结束的Threads中丢失了SOMETIMES

时间:2018-06-01 09:50:46

标签: c# .net multithreading events nullreferenceexception

我对以下代码有一个奇怪的问题,即每分钟都会启动一次。 通常一切正常,但有时HandleCalcStatistikMarkersDone函数会因NullReferenceException而引发错误。

我尝试用代码解释:

我有一个课程策略。这个类大约每分钟启动一次,以计算和更新MySQL数据库中的一些信息。该类在表单上的自动收报机中的不同线程中多次实例化。

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);

        }
    }
}

在上层启动的Strategies线程的内部,有一些额外的线程。 这些线程有一个“DoneEvent”,它在函数结束时引发。

要注意,所有线程在主线程结束之前已经结束,我收集List CalcStatistikMarkersThreads中的所有子线程并等待列表为空。 子线程应该通过ThreadDone事件将自己从上面的List中删除。 但有时找不到搜索到的线程(CalcStatistikMarkersThreads.Find),我得到一个NullReferenceException。 问题是为什么?!

你能告诉我,为什么?并且可能如何预防?

提前致谢。

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; }
        }
    }

}

干杯 空气

0 个答案:

没有答案