Esempio n. 1
0
        public OTCExecutionWindow()
        {
            InitializeComponent();

            mColumns = ColumnObject.GetColumns(ExecutionTreeView);


            ExecutionVMCollection         = new ExecutionCollection(this);
            ExecutionTreeView.ItemsSource = TraderExHandler.Instance.ExecutionVMCollection =
                ExecutionVMCollection;
        }
 public QueuedCollection(Stopwatch sw, long exetime, ExecutionCollection executionCollection)
 {
     StopWatch     = sw;
     ExecutionTime = exetime;
     execollec     = executionCollection;
 }
        private void ExecutionThread()
        {
            Timer.Reset();
            Timer.Start();
            Stopwatch adjuster = Stopwatch.StartNew();

            adjuster.Stop();
            Thread.CurrentThread.Priority = TPriority;
            while (ExecutionThreadActive)
            {
                bool error = false;
                lock (ExecutionOrder)
                {
                    if (ExecutedForward)
                    {
                        ExecutedForward = false;
                        ExecutionOrder  = Executions.Keys.ToArray();
                    }
                    else
                    {
                        ExecutedForward = true;
                        int[] temp = Executions.Keys.ToArray();
                        ExecutionOrder = new int[temp.Length];
                        for (int i = 0; i < temp.Length; i++)
                        {
                            ExecutionOrder[i] = temp[ExecutionOrder.Length - 1 - i];
                        }
                    }
                }
                if ((CurrentInterval - (int)Timer.ElapsedMilliseconds) - (int)adjuster.ElapsedMilliseconds > 0)
                {
                    Thread.Sleep((CurrentInterval - (int)Timer.ElapsedMilliseconds - (int)adjuster.ElapsedMilliseconds));
                }
                else
                {
                    if (ErrorMargin >= 0 && Timer.ElapsedMilliseconds > IdealInterval + ErrorMargin)
                    {
                        error = true;
                    }
                    CurrentInterval = (int)Timer.ElapsedMilliseconds;
                }
                if (!ExecutionThreadActive)
                {
                    return;
                }
                lock (Entries) //TODO Optimize this for multithreading. If several cores are present, run multiple executions at once. MAybe can use ThreadPool just for lines before an exeuction? That way this thread will keep running but executions may nonetheless occur. Make sure to provide critical info that the user may instaed try to fetch from the class and make sure the same operation does not get called twice.
                {
                    if (!ExecutionTimeIncluded)
                    {
                        Timer.Stop();
                    }
                    int        min = CustomIntervalTimes.Count == 0 ? IdealInterval : CustomIntervalTimes.Peek();
                    long       time;
                    List <int> ToBeRemoved = new List <int>();
                    adjuster.Reset();
                    adjuster.Start();
                    foreach (int i in ExecutionOrder)
                    {
                        ExecutionCollection exec = Executions[i];
                        time = Timer.ElapsedMilliseconds;
                        if ((ErrorMargin >= 0 && time + Delays[exec] > IdealInterval + ErrorMargin))
                        {
                            //error!
                            if (!HandleError(exec.Assigner, exec.Disconnector, exec.Executor, Entries[exec], time + Delays[exec]))
                            {
                                continue;
                            }
                        }
                        if (error)
                        {
                            //thread time related error.
                            if (!HandleError(exec.Assigner, exec.Disconnector, exec.Executor, Entries[exec], time + Delays[exec]))
                            {
                                continue;
                            }
                        }
                        time           = Timer.ElapsedMilliseconds;
                        Entries[exec] -= time + Delays[exec];
                        exec.Executor(time + Delays[exec]);
                        Delays[exec] = (int)Timer.ElapsedMilliseconds;

                        if (Entries[exec] < min)
                        {
                            if (Entries[exec] > 0)
                            {
                                //this entry is going to run out of time before interval is finished. Adjust interval accordingly.
                                CustomIntervalTimes.Push((int)Entries[exec]);
                                min = (int)Entries[exec];
                            }
                            else
                            {
                                //this entry has already run out of time.
                                exec.Disconnector();
                                if (CancelCurrentDisAssociation)
                                {
                                    Entries[exec] = 1000000;
                                    CancelCurrentDisAssociation = false;
                                    continue;
                                }
                                //TODO Actually add remover function to also check for when this thread should be stopped.
                                Entries.Remove(exec);
                                Delays.Remove(exec);
                                ToBeRemoved.Add(i);
                            }
                        }
                    }


                    foreach (int i in ToBeRemoved)
                    {
                        Executions.Remove(i);
                        VacantIDs.Enqueue(i);
                    }

                    if (CustomIntervalTimes.Count > 0)
                    {
                        CurrentInterval = CustomIntervalTimes.Pop();
                    }
                    else
                    {
                        CurrentInterval = IdealInterval;
                    }

                    foreach (int i in Executions.Keys)
                    {
                        Delays[Executions[i]] = (int)Timer.ElapsedMilliseconds - Delays[Executions[i]];
                    }
                }

                adjuster.Stop();
                Timer.Reset();
                Timer.Start();

                lock (Queued)
                {
                    long effectivetime;
                    int  min = CurrentInterval;
                    foreach (int i in Queued.Keys)
                    {
                        effectivetime            = Queued[i].StopWatch.ElapsedMilliseconds - Timer.ElapsedMilliseconds;
                        Queued[i].ExecutionTime -= effectivetime;
                        Queued[i].execollec.Executor(effectivetime);
                        Executions.Add(i, Queued[i].execollec);
                        Entries.Add(Queued[i].execollec, Queued[i].ExecutionTime);
                        Delays.Add(Queued[i].execollec, 0);
                        if (min > Queued[i].ExecutionTime)
                        {
                            min = (int)Queued[i].ExecutionTime;
                            CustomIntervalTimes.Push(CurrentInterval);
                            CurrentInterval = min;
                        }
                    }
                    Queued.Clear();
                }

                if (Entries.Count == 0 && Queued.Count == 0)
                {
                    ExecutionThreadActive = false; //stop thread if there is nothing to execute.
                }
            }
        }