gpt4 book ai didi

.net - VB.NET-在单独的线程中进行工作以防止Form挂起

转载 作者:行者123 更新时间:2023-12-03 12:50:10 24 4
gpt4 key购买 nike

我有一个非常简单的窗体,带有一个按钮,该按钮会触发我创建的Sub,该Sub从ActiveDirectory收集数据并将其添加到Excel工作表中。

问题是,当我单击此按钮时,整个表单将挂起。因此,我认为收集数据并将其添加到Excel工作表的操作应在其自己的线程中运行,以使表单不会挂起。可能还需要添加进度条。
但是,进度栏位于主用户窗体上,该窗体在项目运行后即会启动。

为了达到我想要的方式,我需要做什么?

编辑:添加了一些我的代码。我有一个MainForm.vb和一个CodeFile.vb。
我想要CodeFile.vb中的大多数代码,因此比较整齐。

MainForm.vb

Imports User_edit.CodeFile
Imports System.ComponentModel

Public Class MainForm
Private Sub btnImportData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportData.Click
If MyBackgroundWorker.IsBusy <> True Then
MyBackgroundWorker.RunWorkerAsync()
End If
End Sub

Private Sub BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles MyBackgroundWorker.DoWork
ExportADUsers()
End Sub

Private Sub BackgroundWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles MyBackgroundWorker.ProgressChanged
statusBarLabel.Text = (e.ProgressPercentage.ToString)
End Sub

Private Sub BackgroundWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles MyBackgroundWorker.RunWorkerCompleted
statusBarLabel.Text = "Finished"
End Sub
End Class

CodeFile.vb
Imports System.DirectoryServices
Imports System.ComponentModel
Imports System.Threading

Module CodeFile
Public Sub ExportADUsers()
MainForm.MyBackgroundWorker.WorkerReportsProgress = True
MainForm.MyBackgroundWorker.WorkerSupportsCancellation = True

Dim i As Integer

Dim objRootDSE, strRoot, strfilter, strAttributes, strScope
objRootDSE = GetObject("LDAP://RootDSE")
strRoot = objRootDSE.GET("DefaultNamingContext")
strfilter = "(&(objectCategory=Person)(objectClass=User))"
strAttributes = "mail,userPrincipalName,givenName,sn," & _
"initials,displayName,physicalDeliveryOfficeName," & _
"telephoneNumber,mail,wWWHomePage,profilePath," & _
"scriptPath,homeDirectory,homeDrive,title,department," & _
"company,manager,homePhone,pager,mobile," & _
"facsimileTelephoneNumber,ipphone,info," & _
"streetAddress,postOfficeBox,l,st,postalCode,c"
'Scope of the search. Change to "onelevel" if you didn't want to search child OU's
MainForm.statusBarLabel.Text = "Collecting data"
strScope = "subtree"

Dim cn, cmd, rs
cn = CreateObject("ADODB.Connection")
cmd = CreateObject("ADODB.Command")

cn.open("Provider=ADsDSOObject;")
cmd.ActiveConnection = cn
cmd.commandtext = "<LDAP://" & strRoot & ">;" & strfilter & ";" & _
strAttributes & ";" & strScope

rs = cmd.EXECUTE

Dim objExcel, objWB, objSheet

objExcel = CreateObject("Excel.Application")
objWB = objExcel.Workbooks.Add
objSheet = objWB.Worksheets(1)

For i = 0 To rs.Fields.Count - 1
MainForm.MyBackgroundWorker.ReportProgress(i * 10)
objSheet.Cells(1, i + 1).Value = rs.Fields(i).Name
objSheet.Cells(1, i + 1).Font.Bold = True
Next

Dim strExportFile
strExportFile = "C:\users\vsando\desktop\export.xls"

objSheet.Range("A2").CopyFromRecordset(rs)
objSheet.SaveAs(strExportFile)

'Clean up
rs.Close()
cn.Close()
objSheet = Nothing
objWB = Nothing
objExcel.Quit()
objExcel = Nothing

End Sub

注意我在 ExportFromAD中获得的 CodeFile.vb Sub。这实际上是在做的工作。在For每个将数据添加到Excel的循环中,我都放置了 MainForm.MyBackgroundWorker.ReportProgress(i * 10)

问题是,它实际上并没有更新表单上的标签。我觉得这很奇怪,因为表格没有真正悬挂或其他任何东西。它是在尝试访问其他线程还是其他东西?意思是,表单是在它自己的线程上运行的,无法从我的第二个线程访问它?

最佳答案

最好的选择是使用 BackgroundWorker ,因为此类是为这种精确的用例而设计的。

这也允许您call back to the form to update the status bar

关于.net - VB.NET-在单独的线程中进行工作以防止Form挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5936216/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com