防止.Net中的线程被阻塞太长时间

时间:2011-04-05 00:20:16

标签: .net vb.net multithreading windows-services

我有.Net Windows服务。这将托管一个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 _ *()方法表现良好,并且确实有适当的睡眠......我没想到的是,在我没有明确睡眠的地方,每3-6分钟冻结4秒以上,只有一个实例运行在核心i5(四核)上。这对用户体验来说太可怕了,而且我已经把头发拉了几个小时了。

0 个答案:

没有答案