У меня странная проблема со следующим кодом, который запускается примерно каждую минуту.Обычно все работает нормально, но иногда функция HandleCalcStatistikMarkersDone вызывает ошибку из-за NullReferenceException.
Я пытаюсь объяснить с помощью кода:
У меня есть класс Strategies .Этот класс запускается каждую минуту для вычисления и обновления некоторой информации в базе данных 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);
}
}
}
Внутренне в верхнем инициированном потоке стратегий есть несколько дополнительных потоков.Эти потоки имеют «DoneEvent», которое вызывается в конце функции.
Чтобы заметить, что все потоки закончились до окончания основного потока, я собираю все подпотоки в список CalcStatistikMarkersThreads и жду, пока списокпустой.Субпотоки должны удалить себя из верхнего списка через событие ThreadDone.Но иногда искомый поток (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; }
}
}
}
Cheers Air