数据导出表单在文件打开期间/之后偶尔会冻结

时间:2013-07-11 16:22:16

标签: .net vb.net ado.net

我有数据记录软件在导出过程中/之后在某些机器上冻结。在正常使用期间,主窗体是记录数据。如果用户想要将该数据导出到电子表格,他们会按照步骤打开新表单。此表单也保持关注,直到表单关闭。新表单具有选择要导出的数据集的选项。选择数据集后,用户点击导出按钮。代码很长,但我会试着总结一下。

Private Sub Exoprt_btn_Click(ByVal...)

Dim fs As FileStream = Nothing
Dim fw As StreamWriter = Nothing
Dim ...

这个SQL之后的东西恰好填写了文件。这似乎工作正常,因为文件总是打开并正确填充。

在代码的最后我们有

fw.Close()
fs.Close()
fw.Dispose()
fs.Dispose()
System.Diagnostics.Process.Start(FileName)

此时,当代码工作时,电子表格会打开,用户可以根据需要保存或关闭。处理完新文件后,他们可以返回弹出窗口,选择要导出的新数据或关闭窗口并使用主窗体。

但是当软件冻结时,在返回数据记录程序时,数据导出表单通常是空白的,或者有时像按钮和标签这样的对象被部分加载。导出窗口仍保持焦点,但主窗体仍在更新,因为记录了新数据。尝试关闭导出窗口会导致窗口无法响应对话框。重新启动计算机显示后台的所有内容都按预期工作,但窗口的功能无法与之交互。

我尝试通过写入睡眠期和短信来识别恶意代码。

fw.Close()
label1.text = "fw.Close()"
System.Threading.Thread.Sleep(3000)
fs.Close()
label1.text = "fs.Close()"
System.Threading.Thread.Sleep(3000)
...
System.Diagnostics.Process.Start(Filename)
label1.text = "Open File"
System.Threading.Thread.Sleep(3000)

结果是,在关闭Excel之后,如果程序没有冻结,用户只看到“打开文件”,如果是,则只看到“Label1”。

我做了一些研究并且遇到了一些关于线程的想法,因为主窗口是线程化的,并且做了自己的事情,这组代码没有被正确地交叉。我不确定为什么有些计算机运行正常,有些计算机似乎一直锁定。

更多实验:

1)只需打开“导出”窗口,就会导致窗口在记录时冻结。打开导出窗口后,程序将从SQL填充类似datagridview的对象。

2)我可以使用另一个日志记录软件实例在原始实例记录时获取数据。这仍然会导致主实例的主窗口锁定。

3)一台曾经表现出这些症状的计算机似乎已被其恶魔驱除了。

2 个答案:

答案 0 :(得分:5)

看一下BackgroundWorker课程。 This post应该让你入门。要更新label1.Text,请处理ProgressChanged事件并相应地传递进度值。

答案 1 :(得分:2)

  1. 使用导出代码作为函数创建一个类
  2. 在类的顶部创建/添加委托函数exportHandler
  3. 在表单内部,使用导出功能为新类添加处理程序。
  4. 创建一个callbackhandler方法来接收执行导出功能的线程的状态。使用callbackhandler调用一个更新ui函数,该函数检查线程是从UI运行还是另一个线程。 (Me.InvokeRequired检查这个)
  5. 在Form btn click事件内部使用targetHandlerExportData调用调用导出数据Async。

    Private targetHandlerExportData As ClassName.exportHandler = AddressOf objNewClass.exportData
    
    
    Private callbackHandler As AsyncCallback _
                               = AddressOf MyCallbackMethod
    
    
    
    Sub MyCallbackMethod(ByVal ar As IAsyncResult)
        '*** this code fires at completion of each asynchronous method call
        Try
    
            Dim retval As Boolean = targetHandlerExportData.EndInvoke(ar)
            If retval = True Then
                Console.Write(retval)
            End If
            UpdateUI("Task complete")
    
        Catch ex As Exception
            Dim msg As String
            msg = "Error: " & ex.Message
            UpdateUI(msg)
    
        End Try
    End Sub
    
    Sub UpdateUI(ByVal statusMessage As String)
        If Me.InvokeRequired Then
            Dim handler As New UpdateUIHandler(AddressOf UpdateUI_Impl)
            Dim args() As Object = {statusMessage}
            Me.BeginInvoke(handler, args)
    
        Else
            UpdateUI_Impl(statusMessage)
        End If
    End Sub
    
    Delegate Sub UpdateUIHandler(ByVal statusMessage As String)
    
    Sub UpdateUI_Impl(ByVal statusMessage As String)
        Me.sbMain.Panels("Status").Text = statusMessage
    End Sub
                      Private Sub Export_btn_Click()
                      Dim result As IAsyncResult = targetHandlerExportData.BeginInvoke(callbackHandler, Nothing)  
                      End Sub