Предотвратить слишком долгую блокировку потока в .Net - PullRequest
0 голосов
/ 05 апреля 2011

У меня есть служба Windows .Net. Здесь размещается служба WCF и несколько «симуляций», которые выполняются в отдельных потоках ... каждая симуляция была настроена, поэтому она очень последовательна в действии, чтобы предотвратить одновременное использование слишком большого количества потоков. У меня есть несколько вызовов Thread.Sleep (100), и я ожидаю, что у меня не будет такой большой проблемы. Однако бывают случаи, когда после нескольких минут работы поток медленно зависает на медленной машине до 30 секунд. Я сделал несколько настроек, и теперь это происходит немного реже, и на моей локальной машине он останавливается только на 4-7 секунд, но это слишком много для ожидаемого опыта пользователя. Ожидается, что клиентские сообщения должны быть не более 2 секунд от доступности.

Я уже устанавливаю приоритет потока на «Наивысший», что и объясняет, насколько это возможно, и не происходит ни в одном конкретном блоке кода. Любые другие предложения? Я мог бы настроить пул потоков и / или запустить все операции как объединенные выражения из одного потока менеджера во всех симуляциях. Однако это уже происходит с одним потоком, работающим в среде разработчика. Я действительно не хочу проходить время разработки, чтобы реорганизовать эту область кода, не зная, что это решит мою проблему.

 Public Sub StartSim()
        Log.Info("SimulationInstance.StartSim", String.Format("Starting the simulation instance: {0}", InstanceEntity.Guid), Nothing)

        'initialize thread, and start it
        SyncLock _lock
            If _runner IsNot Nothing Then
                Return 'running
            End If
            _runner = New Thread(New ThreadStart(AddressOf RunSimulation))
            _runner.Priority = ThreadPriority.Highest
            _runner.Start()
        End SyncLock
    End Sub

    Private Sub RunSimulation()
        Me.StartedOn = DateTime.Now
        Me.StartedOnMinutes = TimeSpan.FromMinutes(InstanceEntity.MinutesTaken)

        InstanceEntity.StartedOn = Me.StartedOn

        TranscriptLog.AppendTranscriptLog(
            DB,
            InstanceEntity.Guid,
            Guid.Empty,
            InstanceEntity.Scenario,
            "Simulation instance started.",
            "from",
            "to",
            "Simulation instance started.",
            "entry",
            InGameTime,
            "event",
            Nothing,
            0,
            ""
        )

        While True
            Try
                ' This is the master simulation controller

                RunSimulation_HandleMessages()

                RunSimulation_CheckPulse()

                RunSimulation_IdleCheck()

                RunSimulation_ServiceUnits()

                RunSimulation_AutoSave()

            Catch ex As ThreadAbortException
                'closing
                Log.Info("SimulationInstance.RunSimulation", "Ending Simulation", String.Empty)
                TranscriptLog.AppendTranscriptLog(
                    DB,
                    InstanceEntity.Guid,
                    Guid.Empty,
                    InstanceEntity.Scenario,
                    "Simulation instance stopped.",
                    "from",
                    "to",
                    "Simulation instance stopped.",
                    "entry",
                    InGameTime,
                    "event",
                    Nothing,
                    0,
                    ""
                )
                SaveSim()
                Return ' done running

            Catch ex As Exception
                Log.Critical("SimulationInstance.RunSimulation", "Critical Error", ex.ToString())

                Dim dialog = <dialog>
                                <title>Server Internal Error</title>
                                <image>dialog_idle.png</image>
                                <message><%= New XCData(String.Format("<p><b>Server Error:</b></p><p><hr>{0}<hr></p><p>Terminating the simulation.</p><p>Please try again.</p>", ex.Message)) %></message>
                                <buttons>
                                    <button action="exit">Exit</button>
                                </buttons>
                            </dialog>

                BroadcastMessage("dialog", "IMAGE+TEXT", Nothing, Guid.NewGuid().ToString(), dialog)

                StopSim()
                Return 'done running

            End Try
        End While
    End Sub

Да, это VB (не мой выбор, но я получаю XML-литералы). Каждый из методов RunSimulation _ * () хорошо себя ведет и имеет надлежащие сны ... Чего я не ожидаю, так это замораживание на 4+ секунды каждые 3-6 минут в местах, где я явно не спал , на котором только один экземпляр работает на ядре i5 (четырехъядерный). Это было бы ужасно для пользователя, и я уже несколько часов выдергиваю волосы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...