public void Tick()
        {
            var flowBlock = SuppressFlow();

            Task[] tasks;

            lock (m_runningTasks)
            {
                tasks = m_runningTasks.Values.ToArray();
            }

            // ticks should be reentrant (Tick might invoke TriggerEvent, e.g.)
            Dictionary <int, Task> lastInTickTasks;

            lock (m_inTickTasksLock)
            {
                lastInTickTasks = m_inTickTasks;

                m_inTickTasks = new Dictionary <int, Task>();
            }

            do
            {
                using (var scope = new ProfilerScope(() => "task iteration"))
                {
                    foreach (var task in tasks)
                    {
                        InvokeTryExecuteTask(task);

                        if (task.Exception != null)
                        {
                            Debug.WriteLine("Exception thrown by a task: {0}", task.Exception.ToString());
                        }

                        if (task.IsCompleted || task.IsFaulted || task.IsCanceled)
                        {
                            lock (m_runningTasks)
                            {
                                m_runningTasks.Remove(task.Id);
                            }
                        }
                    }

                    lock (m_inTickTasksLock)
                    {
                        tasks = m_inTickTasks.Values.ToArray();
                        m_inTickTasks.Clear();
                    }
                }
            } while (tasks.Length != 0);

            lock (m_inTickTasksLock)
            {
                m_inTickTasks = lastInTickTasks;
            }

            flowBlock?.Undo();
        }
Exemple #2
0
        public void Tick()
        {
            IsProfiling = ProfilerIsRecording();

            if (GameInterface.SnapshotStackBoundary(out var b))
            {
                ScriptHost.SubmitBoundaryStart(b, b.Length);
            }

            try
            {
                using (var scope = new ProfilerScope(() => "c# cleanup"))
                {
                    ScriptContext.GlobalCleanUp();
                }

                using (var scope = new ProfilerScope(() => "c# deferredDelay"))
                {
                    var delays = ms_delays.ToArray();
                    var now    = DateTime.UtcNow;

                    foreach (var delay in delays)
                    {
                        if (now >= delay.Item1)
                        {
                            using (var inScope = new ProfilerScope(() => delay.Item3))
                            {
                                try
                                {
                                    BaseScript.CurrentName = delay.Item3;
                                    delay.Item2(new DummyAsyncResult());
                                }
                                finally
                                {
                                    BaseScript.CurrentName = null;
                                }
                            }

                            ms_delays.Remove(delay);
                        }
                    }
                }

                using (var scope = new ProfilerScope(() => "c# schedule"))
                {
                    foreach (var script in ms_definedScripts.ToArray())
                    {
                        script.ScheduleRun();
                    }
                }

                using (var scope = new ProfilerScope(() => "c# tasks"))
                {
                    CitizenTaskScheduler.Instance.Tick();
                }

                using (var scope = new ProfilerScope(() => "c# syncCtx"))
                {
                    CitizenSynchronizationContext.Tick();
                }
            }
            catch (Exception e)
            {
                PrintError("tick", e);
            }
            finally
            {
                ScriptHost.SubmitBoundaryStart(null, 0);
            }
        }