Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net Winform在同步Sql调用之间更新GUI_Sql_Vb.net_Winforms_User Interface_Synchronous - Fatal编程技术网

Vb.net Winform在同步Sql调用之间更新GUI

Vb.net Winform在同步Sql调用之间更新GUI,sql,vb.net,winforms,user-interface,synchronous,Sql,Vb.net,Winforms,User Interface,Synchronous,大家好,我已经搜索了很多,但是找不到一个真正适合这种情况的结果 我有一个(目前)用VB.Net编写的单线程应用程序,主要处理步骤是treeview控件中的12个检查列表项。程序依次执行步骤(函数和存储过程),并在继续之前检查结果 步骤(大大简化)如下: 1.从txt文件导入数据 2.将其大容量插入数据库 3.做一些处理 4.使用该数据从链接服务器在复杂连接中通过网络检索更多相关数据。 5.使用结果更新本地数据库 6.做更多的处理 7.将最终结果插入不同服务器上的不同数据库 我不会详细说明所有必须

大家好,我已经搜索了很多,但是找不到一个真正适合这种情况的结果

我有一个(目前)用VB.Net编写的单线程应用程序,主要处理步骤是treeview控件中的12个检查列表项。程序依次执行步骤(函数和存储过程),并在继续之前检查结果

步骤(大大简化)如下: 1.从txt文件导入数据 2.将其大容量插入数据库 3.做一些处理 4.使用该数据从链接服务器在复杂连接中通过网络检索更多相关数据。 5.使用结果更新本地数据库 6.做更多的处理 7.将最终结果插入不同服务器上的不同数据库

我不会详细说明所有必须这样做的原因,例如(公司内不同的服务器所有者、服务器之间缺乏信任、对某些数据库的只读访问等),但问题在于步骤4

根据(外部)服务器上的处理负载和导入文件中的数据量,执行此步骤可能需要1-1/2小时。由于这是一个单线程应用程序,gui将冻结,等待从链接服务器检索数据

除了桌面上的灰色块(由于没有gui更新),该程序运行良好

尝试的解决方案: 1) 我尝试了计时器的建议来刷新表单,但没有成功

2) 我已经尝试使用后台工作进程,但无法让应用程序在程序继续之前等待结果

3) 我还尝试了不同的线程示例,但没有成功。所有其他步骤完成得如此之快,以至于gui永远无法释放,但我不会反对在这个应用程序中线程化所有sql调用

在我这么做的所有时间里,这是我第一次在网络上找不到解决方案,以前从未需要发布过,因此非常感谢您对这件事的帮助

--编辑

以下是我尝试过的: 谢谢你的快速回复

我使用了这里描述的过程:(在将其转换为vb.net之后)。但是,该程序恰好通过了步骤(底部的案例编号6)

导入System.Runtime.InteropServices
导入系统线程
导入System.ComponentModel
私有子bgw_ProgressChanged(ByVal发送方作为System.Object,ByVal e作为System.ComponentModel.ProgressChangedEventArgs)
'报告进度条更改
进度值=e.ProgressPercentage
端接头
私有子bgw_RunWorkerCompleted(ByVal发送方作为System.Object,ByVal e作为System.ComponentModel.RunWorkerCompletedEventArgs)
如果(如取消),则
WriteStatus(“操作已取消”)
bRetval=False
其他的
WriteStatus(“操作已完成”)
bRetval=True
如果结束
端接头
'后台工作者工作方法。我们将在这里执行繁重的任务。
私有子bgw_DoWork(ByVal发送方作为对象,ByVal e作为DoWorkEventArgs)
Dim Sql As String=“获取数据”
Dim cmd作为新的SqlCommand(Sql、ConnLocal)
cmd.CommandTimeout=9000'2个半小时
尝试
尺寸i为整数=0
ConnLocal.Open()
'ImportRowCount=cmd.ExecuteScalar()
将dr设置为SqlDataReader
dr=cmd.ExecuteReader()
而里德博士
i=i+1
'向后台工作人员类的backgroundworkerprogress.changed事件报告
bgw.进度报告(一)
线程。睡眠(1)
'呼叫并检查操作的取消是否挂起。如果返回true
'DoWorkEventArgs对象取消该操作。
如果bgw.CancellationPending,则
e、 取消=真
返回
如果结束
ImportRowCount=CInt(dr(0))
结束时
特例
WriteStatus(“获取ALS数据错误:&ex.Message”)
e、 取消=真
返回
最后
ConnLocal.Close()
结束尝试
WriteStatus(“成功获取ALS数据”)
e、 取消=错误
返回
端接头
私有子bgw_ProgressChanged(ByVal发送方作为System.Object,ByVal e作为System.ComponentModel.ProgressChangedEventArgs)
'报告进度条更改
进度值=e.ProgressPercentage
端接头
私有子bgw_RunWorkerCompleted(ByVal发送方作为System.Object,ByVal e作为System.ComponentModel.RunWorkerCompletedEventArgs)
如果(如取消),则
WriteStatus(“操作已取消”)
bRetval=False
其他的
WriteStatus(“操作已完成”)
bRetval=True
如果结束
端接头
私有子进程CheckedNodes(ByVal parentNode作为TreeNode)
将成功设置为布尔值=False
对于parentNode.Nodes中的每个childNode作为树节点
ProgBar+=BarSeg
如果ProgBar>100,则
ProgBar=100
如果结束
pb1.值=程序条
我
如果是childNode,则选中
选择Case childNode.Name
案例“节点1”
“1.清除本地工作表
SetChild(childNode,“True”)
Success=DoCleanup()
如果成功是真的那么
SetChild(childNode,“错误”)
游标=游标。默认值
出口接头
如果结束
SetChild(childNode,“False”)
案例“节点2”
'2.清除服务器入口表
SetChild(childNode,“True”)
成功=截断插入(“文档清理”)
如果成功是真的那么
SetChild(childNode,“错误”)
游标=游标。默认值
出口接头
如果结束
SetChild(childNode,“False”)
案例“节点3”
"3,装载
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
public class SyncEvents
{
    private EventWaitHandle _newItemEvent;

private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;

public SyncEvents()
{
    _newItemEvent = new AutoResetEvent(false);
    _exitThreadEvent = new ManualResetEvent(false);
    _eventArray = new WaitHandle[2];
    _eventArray[0] = _newItemEvent;
    _eventArray[1] = _exitThreadEvent;
}

public EventWaitHandle ExitThreadEvent
{
    get { return _exitThreadEvent; }
}

public EventWaitHandle NewItemEvent
{
    get { return _newItemEvent; }
}

public WaitHandle[] EventArray
{
    get { return _eventArray; }
}
}
public class RunItem
{

public int SequenceToRun { get; set; }

}

public class ItemRunner
{

private SyncEvents _syncEvents;
private Queue<RunItem> _items;
private Thread _processThread;

public ItemRunner(SyncEvents events, Queue<RunItem> items)
{
   this._syncEvents = events;
   this._items = items;
}

public void Start()
{
   this._processThread = new Thread(this.Run);
   this._processThread.IsBackground = true;
   this._processThread.Start();
}

private void Run()
{
   try
   {
            while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
            {
                RunItem item = null;

                lock (this._items)
                {
                    if (this._items.Count > 0)
                    {
                        item = this._items.Dequeue();
                        if (item != null)
                        this.ProcessItem(item);
                        this._syncEvents.NewItemEvent.Set();
                    }
                    else
                    {
                      this._syncEvents.ExitThreadEvent.Set();
                    }

                }
            }
   }
   catch (Exception ex)
   {
      // do something to log your exception here
      // you should have the try catch since you are running in a thread and if it 
      // throws an exception it could kill your entire app.

   }
}

private void ProcessItem(RunItem item)
{
      // Do your item processing here.
   // You could have a final item that executes the 
  // this._syncEvents.ExitThreadEvent.Set(); so that it actually will stop waiting 

}
}