У меня есть служба 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 (четырехъядерный). Это было бы ужасно для пользователя, и я уже несколько часов выдергиваю волосы.