本文介绍了VB.NET后台工作者仍然冻结形式。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 大家好, 你能帮我解决这个问题。 Backgroundworker应该使表单响应,但我的代码没有这样做。以下代码是否有问题。 私人 代表 Sub EncyptFilesDelegate() 私有 Sub EncyptFiles() 如果 我 .InvokeRequired 然后 我 .Invoke( New EncyptFilesDelegate( AddressOf EncyptFiles),新 对象(){}) 否则 ' 更多代码(声明,创建文件夹等) 对于 每个文件名作为 String 在 frmMain.OpenFileDialog1.FileNames FileCrypt(Filename,save&文件夹(索引)& \& file,UniqueID,Crypt.CryptAction.Encrypt) 下一步 结束 如果 结束 Sub 私有 Sub FileCrypt( ByVal InputFile 作为 字符串, ByVal OutputFile 作为 字符串, ByVal 密码作为 字符串, ByVal 方向 As Crypt.CryptAction) ' 更多代码(声明,获取密钥,等) 如果 Direction = Crypt.CryptAction.Encrypt 那么 CryptoStream = 新 Security.Cryptography.CryptoStream(Output,Rijndael.CreateEncryptor(Key,IV),Security.Cryptography.CryptoStreamMode.Write) Else CryptoStream = 新 Security.Cryptography.CryptoStream(输出,Rijndael.CreateDecryptor(Key,IV),Security.Cryptography.CryptoStreamMode.Write) 结束 如果 Dim persecond 作为 长 = 0 Dim watch 作为 新秒表观看。开始() 在处理& LT; FileLength CurrentBlock = Input.Read(Buffer, 0 , 4096 ) CryptoStream .Write(Buffer, 0 ,CurrentBlock)已处理=已处理+ CLng (CurrentBlock) ' PROGRESSBAR TotalProcessed = TotalProcessed + CLng (CurrentBlock) 如果 watch.ElapsedMilliseconds> 1000 然后 ProgressBar1.Value = CInt ((TotalProcessed / TotalLength)* 100 ) Me .Text = CInt ((TotalLength - TotalProcessed)/ persecond)& 剩余秒数 persecond = 0 watch.Restart() 结束 如果 persecond = persecond + CLng (CurrentBlock) 结束 while watch。 Stop () CryptoStream.Close() Input.Close() Output.Close() 结束 Sub 私有 Sub BackgroundWorker1_DoWork(发件人 As 对象,e As System.ComponentModel.DoWorkEventArgs)句柄 BackgroundWorker 1.DoWork 如果 Action = ProgressAction.Encypt 那么 Dim encypt As EncyptFilesDelegate = AddressOf EncyptFiles encypt .Invoke() MsgBox( 完成) 结束 如果 结束 Sub 我尝试将 FileCrypt 放在 EncyptFiles 但结果相同。 谢谢... 解决方案 原因应该是相当明显的: 私人 Sub EncyptFiles() 如果 我 .InvokeRequired 然后 我 .Invoke(新 EncyptFilesDelegate( AddressOf EncyptFiles),新 Object (){}) Else ' 更多代码(声明,创建文件夹等) 对于 每个文件名作为 字符串 In frmMain.OpenFileDialog1.FileNames FileCrypt(Filename,save&文件夹(索引)& \& file,UniqueID,Crypt.CryptAction.Encrypt) 下一步 结束 如果 结束 Sub 您的 BackgroundWorker 启动新线程以提升 DoWork event; DoWork 事件处理程序调用 EncryptFiles ; EncryptFiles 方法注意到它在后台线程上运行,而调用调用将工作移回UI线程; 在UI线程上继续工作。 解决方案非常简单: 删除 InvokeRequired / 从 EncryptFiles 方法调用代码。 使用 BackgroundWorker 's ReportProgress 方法 [ ^ ]将%进度和文本传递回UI; 处理 BackgroundWorker 的 ProgressChanged 事件 [ ^ ]更新文本和进度条。 Hello Everyone,Can you help me with this one. Backgroundworker should make the Form responsive but my code is not doing that. Is there something wrong with the below code. Private Delegate Sub EncyptFilesDelegate()Private Sub EncyptFiles() If Me.InvokeRequired Then Me.Invoke(New EncyptFilesDelegate(AddressOf EncyptFiles), New Object() {}) Else 'MORE CODE (Declaration, Create Folder, etc) For Each Filename As String In frmMain.OpenFileDialog1.FileNames FileCrypt(Filename, save & folders(Index) & "\" & file, UniqueID, Crypt.CryptAction.Encrypt) Next End IfEnd SubPrivate Sub FileCrypt(ByVal InputFile As String, ByVal OutputFile As String, ByVal Password As String, ByVal Direction As Crypt.CryptAction) 'MORE CODE (Declaration, Getting Key, etc) If Direction = Crypt.CryptAction.Encrypt Then CryptoStream = New Security.Cryptography.CryptoStream(Output, Rijndael.CreateEncryptor(Key, IV), Security.Cryptography.CryptoStreamMode.Write) Else CryptoStream = New Security.Cryptography.CryptoStream(Output, Rijndael.CreateDecryptor(Key, IV), Security.Cryptography.CryptoStreamMode.Write) End If Dim persecond As Long = 0 Dim watch As New Stopwatch watch.Start() While Processed < FileLength CurrentBlock = Input.Read(Buffer, 0, 4096) CryptoStream.Write(Buffer, 0, CurrentBlock) Processed = Processed + CLng(CurrentBlock) 'PROGRESSBAR TotalProcessed = TotalProcessed + CLng(CurrentBlock) If watch.ElapsedMilliseconds > 1000 Then ProgressBar1.Value = CInt((TotalProcessed / TotalLength) * 100) Me.Text = CInt((TotalLength - TotalProcessed) / persecond) & " seconds remaining" persecond = 0 watch.Restart() End If persecond = persecond + CLng(CurrentBlock) End While watch.Stop() CryptoStream.Close() Input.Close() Output.Close()End SubPrivate Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork If Action = ProgressAction.Encypt Then Dim encypt As EncyptFilesDelegate = AddressOf EncyptFiles encypt.Invoke() MsgBox("Done") End IfEnd SubI try putting the FileCrypt inside the EncyptFiles but same result.Thanks... 解决方案 The reason should be fairly obvious:Private Sub EncyptFiles() If Me.InvokeRequired Then Me.Invoke(New EncyptFilesDelegate(AddressOf EncyptFiles), New Object() {}) Else 'MORE CODE (Declaration, Create Folder, etc) For Each Filename As String In frmMain.OpenFileDialog1.FileNames FileCrypt(Filename, save & folders(Index) & "\" & file, UniqueID, Crypt.CryptAction.Encrypt) Next End IfEnd SubYour BackgroundWorker kicks off a new thread to raise the DoWork event;The DoWork event handler calls EncryptFiles;The EncryptFiles method notices that it's running on a background thread, and calls Invoke to move the work back to the UI thread;Work continues on the UI thread.The solution is fairly simple:Remove the InvokeRequired / Invoke code from your EncryptFiles method.Use the BackgroundWorker's ReportProgress method[^] to pass the % progress and text back to the UI;Handle the BackgroundWorker's ProgressChanged event[^] to update text and progress bar. 这篇关于VB.NET后台工作者仍然冻结形式。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-20 20:27