我对以下代码有一个奇怪的问题,即每分钟都会启动一次。 通常一切正常,但有时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; }
}
}
}
干杯 空气