#.net #sql-server #vb.net #sql-server-2008 #timer
#.net #sql-сервер #vb.net #sql-server-2008 #таймер
Вопрос:
Я работаю над настольным приложением в VB.net 2005 год. Приложение содержит таймер с интервалом в 1 минуту. Каждый раз, когда таймер отсчитывает время, выполняется набор функций, в основном связанных с базой данных. Изначально приложение работает нормально. В процессах (диспетчер задач) загрузка ЦП достигает 100% при каждом вызове таймера. Но временной интервал составляет около 1 секунды (незначительный). Однако по прошествии времени и примерно через 20 часов промежуток времени timer_tick увеличивается примерно до 20-30 секунд. В этот период загрузка процессора составляет 100%, и приложение не отвечает. Постепенно промежуток времени timer_tick увеличивается до 1 минуты, а загрузка процессора застревает на 100%, и приложение не отвечает. Все объекты расположены правильно. Более того, эта проблема связана с процессорами pentium 4. Приложение отлично работает на core 2 duo.
Таймер содержит 4 функции… Я добавляю несколько из этих функций..
Public Sub SetNotes()
Dim dtOld As DataTable
Dim dtNew As DataTable
Dim oApptTasks As New AppointmentsAndTasks
dtOld = oApptTasks.PopulateAllTasks ' get the source table
dtNew = dtOld.Clone ' make new table ad clone of old table
If btnShowNotes.Text = "Hide Notes" Then
For Each item As System.Data.DataRow In dtOld.Rows
If Not IsDBNull(item("Notes")) Then
If item("Notes") <> "" Then ' add only if not null and not blank
item("Task") = item("Task") amp; vbCrLf amp; item("Notes") ' concatenate the notes field
End If
End If
dtNew.ImportRow(item) ' import modified row to new table
Next
grdcTask.DataSource = SetAssignedTo(dtNew) ' set the datasource
grdcTask.DataSource = SetAssignedFrom(grdcTask.DataSource) ' set the datasource
repMemoNotes.LinesCount = 0 ' adjust the height of custom field
Else
grdcTask.DataSource = SetAssignedTo(dtOld) ' set the datasource
grdcTask.DataSource = SetAssignedFrom(grdcTask.DataSource) ' set the datasource
End If
End Sub
Теперь это одна из четырех функций, вызываемых таймером…который использует следующий код для извлечения данных из базы данных.
Using conn As New SqlConnection(glbSqlConnString)
Try
conn.Open()
Dim dbDataAdapter As New SqlDataAdapter(oStrQueryBuilder.ToString, conn)
dbDataAdapter.Fill(dbDataTable)
Catch ex As Exception
EventLog.WriteLog("App", ex.ToString, EventLogEntryType.Error)
Finally
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Try
End Using
Многие запросы Select, Update и delete выполняются по таймеру.
Эта проблема возникает, когда я использую около 7000 записей в базе данных. При меньшем количестве записей проблема не возникает. Итак, могут ли SQL-запросы быть причиной этого.
Не могли бы вы подсказать, что может быть причиной утечки памяти?
С нетерпением жду помощи. Заранее спасибо.
Комментарии:
1. Посмотрите на счетчики производительности, особенно с точки зрения сборки мусора. Вы профилировали свой код, чтобы узнать, куда идет процессор?
2. Можем ли мы увидеть что-то помимо теории??? что-то происходит, но, не видя, трудно понять, что именно…
3. Я не использовал профилировщик. Но заметили, что код внутри таймера, который содержит несколько взаимодействий с sql server, создает проблему. Я отключил таймер, и проблема исчезла.
4. Используете ли вы неуправляемые ресурсы? Вы уверены, что все утилизируется правильно? Пожалуйста, опубликуйте код, который выполняется в событии Tick.
5. @GeekOnDemand Публикует код, облегчающий помощь вам.
Ответ №1:
Я бы рекомендовал использовать некоторые инструменты профилировщика. Есть несколько бесплатных, но, по моему опыту, коммерческие инструменты стоят того.
Например, ANTS Profiler. http://www.red-gate.com/products/dotnet-development / Может быть, вам достаточно оценки perios?
Ответ №2:
Здесь я делаю предположение, поскольку вы упомянули, что проблема возникает только тогда, когда количество записей превышает 7000; это может быть ситуация, когда следующий триггер таймера сработал до того, как предыдущее событие завершило свою работу с базой данных. Это может привести к отставанию в выполнении операций, которые необходимо выполнить, и со временем их становится все больше.
Я бы рекомендовал вам убедиться, что в любой момент времени выполняется только 1 набор операций. Например, используйте приведенную ниже логику для запуска функции таймера
Function TimerFunction
'Diable Timer - This will disable the timer so that no more timer events are triggered'
timer1.Enabled = False
Function1()
Function2()
Function3()
Function4()
'Enable Timer - Now enable the timer again so that it can continue normally'
timer1.Enabled=True
End
Но вам обязательно нужно будет профилировать работу вашей базы данных и настроить операцию, которая задерживает выполнение программы. Вызывает беспокойство то, что производительность ваших приложений начинает отставать всего от 7000 записей.
Надеюсь, это поможет.