тема Привет всем, я интенсивно искал это, но не смог найти результат, который действительно соответствует этой ситуации.
У меня (в настоящее время) однопоточное приложение, написанное на VB.Net. Основные этапы обработки - 12 проверенных элементов списка в древовидном элементе управления. Программа выполняет шаги (функции и хранимые процедуры) по очереди и проверяет результат, прежде чем продолжить.
Шаги (значительно упрощенные):
1. Импорт данных из текстового файла
2. Массовая вставка в базу данных
3. Сделайте некоторую обработку
4. Используйте эти данные, чтобы получить гораздо больше связанных данных по сети в сложном соединении со связанного сервера.
5. Обновите локальную базу данных с результатами
6. Делайте больше обработки
7. Вставьте окончательные результаты в другую базу данных на другом сервере.
Я не буду вдаваться во все причины, по которым это нужно было сделать, например (разные владельцы серверов в компании, отсутствие доверия между серверами, доступ только для чтения к определенным базам данных и т. Д.), Но проблема заключается в шаге 4 .
В зависимости от загрузки обработки на (стороннем) сервере и объема данных в файле импорта этот шаг может занять 1-1 / 2 часа. Поскольку это однопоточное приложение, графический интерфейс останавливается в ожидании получения данных со связанного сервера.
Помимо серого блока на рабочем столе (из-за отсутствия обновлений графического интерфейса), программа работает отлично.
Попытки решения:
1) Я попытался предложить таймер для обновления формы безуспешно.
2) Я пытался использовать фоновый рабочий процесс, но не смог заставить приложение ждать результата, прежде чем программа продолжила.
3) Я также пробовал разные примеры потоков, но безуспешно. Все остальные шаги выполняются так быстро, что графический интерфейс никогда не останавливается, но я бы не стал тратить время на все мои вызовы sql в этом приложении.
За все время, что я занимался этим, я впервые не смог найти решение в Интернете, и мне никогда не приходилось публиковать его ранее, поэтому помощь в этом вопросе будет принята с благодарностью.
- редактировать
Вот что я попробовал:
Спасибо за быстрый ответ.
Я использовал описанный здесь процесс: http://midnightprogrammer.net/post/Using-Background-Worker-in-C.aspx (после преобразования его в vb.net). но программа проскочила сразу после шага (Дело № 6 внизу).
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.ComponentModel
Private Sub bgw_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
'Report progress bar change
progress.Value = e.ProgressPercentage
End Sub
Private Sub bgw_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
If (e.Cancelled) Then
WriteStatus("Operation Cancelled")
bRetval = False
Else
WriteStatus("Operation Completed")
bRetval = True
End If
End Sub
'Background worker DoWork method. Here we will perform our heavy duty tasks.
Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim Sql As String = "Get_ALS_Data"
Dim cmd As New SqlCommand(Sql, ConnLocal)
cmd.CommandTimeout = 9000 ' 2 and a half hours
Try
Dim i As Integer = 0
ConnLocal.Open()
'ImportRowCount = cmd.ExecuteScalar()
Dim dr As SqlDataReader
dr = cmd.ExecuteReader()
While dr.Read()
i = i + 1
'report to the backgroundworkerprogress.changed event of the background worker class
bgw.ReportProgress(i)
Thread.Sleep(1)
'Call and check if the cancellation of the operation is pending. If returned true
'DoWorkEventArgs object cancels the operation.
If bgw.CancellationPending Then
e.Cancel = True
Return
End If
ImportRowCount = CInt(dr(0))
End While
Catch ex As Exception
WriteStatus("Get ALS Data error: " & ex.Message)
e.Cancel = True
Return
Finally
ConnLocal.Close()
End Try
WriteStatus("Get ALS Data completed successfully.")
e.Cancel = False
Return
End Sub
Private Sub bgw_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
'Report progress bar change
progress.Value = e.ProgressPercentage
End Sub
Private Sub bgw_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
If (e.Cancelled) Then
WriteStatus("Operation Cancelled")
bRetval = False
Else
WriteStatus("Operation Completed")
bRetval = True
End If
End Sub
Private Sub ProcessCheckedNodes(ByVal parentNode As TreeNode)
Dim Success As Boolean = False
For Each childNode As TreeNode In parentNode.Nodes
ProgBar += BarSeg
If ProgBar > 100 Then
ProgBar = 100
End If
pb1.Value = ProgBar
Me.Refresh()
If childNode.Checked Then
Select Case childNode.Name
Case "Node1"
'1. Clear local work tables
SetChild(childNode, "True")
Success = DoCleanup()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node2"
'2. Clear Server Intake table
SetChild(childNode, "True")
Success = TruncateInserts("DoCleanUp")
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node3"
'3. Load the temp table
SetChild(childNode, "True")
Success = LoadMyTempTable()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node4"
'4. Load the data from the temp table to the local database
SetChild(childNode, "True")
Success = BulkCopy_Intake()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node5"
'5. Get Intake Dup's
SetChild(childNode, "True")
Success = GetIntakeDups()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
**Case "Node6"
'6. Get the matching data from the ALS database
SetChild(childNode, "True")
'Success = GetALS_Data()
bgw.RunWorkerAsync()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")**
Case "Node7"
'7. Get Core Dup's
SetChild(childNode, "True")
Success = GetCoreDups()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node8"
'8. Process
SetChild(childNode, "True")
Success = Process()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node9"
'9. Export NotFound
SetChild(childNode, "True")
Success = ExportNotFound()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node10"
'10. Move Inserts
SetChild(childNode, "True")
Success = MoveInserts()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node11"
'11. Backup
SetChild(childNode, "True")
Success = Backup()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case "Node12"
SetChild(childNode, "True")
'Success = LoadDc()
If Success <> True Then
SetChild(childNode, "Error")
Cursor = Cursors.Default
Exit Sub
End If
SetChild(childNode, "False")
Case Else
'Ignore it
End Select
Else
childNode.ImageIndex = 0
childNode.SelectedImageIndex = 0
End If
ProcessCheckedNodes(childNode)
Next
pb1.Value = 100
End Sub**strong text**
Public Function GetALS_Data() As Boolean
'refresh the form while waiting for the ALS data
Dim sAcct As String = ""
Dim Sql As String = "Get_ALS_Data"
Dim cmd As New SqlCommand(Sql, ConnLocal)
cmd.CommandTimeout = 9000 ' 2 and a half hours
Try
ConnLocal.Open()
ImportRowCount = cmd.ExecuteScalar()
Catch ex As Exception
WriteStatus("Get ALS Data error: " & ex.Message)
Return False
Finally
ConnLocal.Close()
End Try
WriteStatus("Get ALS Data completed successfully.")
Return True
End Function