我有数据记录软件在导出过程中/之后在某些机器上冻结。在正常使用期间,主窗体是记录数据。如果用户想要将该数据导出到电子表格,他们会按照步骤打开新表单。此表单也保持关注,直到表单关闭。新表单具有选择要导出的数据集的选项。选择数据集后,用户点击导出按钮。代码很长,但我会试着总结一下。
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)一台曾经表现出这些症状的计算机似乎已被其恶魔驱除了。答案 0 :(得分:5)
看一下BackgroundWorker课程。 This post应该让你入门。要更新label1.Text,请处理ProgressChanged事件并相应地传递进度值。
答案 1 :(得分:2)
在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