Backgroundworker不会将文件移动到正确的目录vb.net

时间:2014-11-24 18:17:33

标签: vb.net windows multithreading backgroundworker

我正在开发一个应用程序,它将文件提取并移动到特定目录...同时删除它用于提取的文件,等等等。就像一个基本的安装程序。

以下是我遇到的问题:

   Dim DirectoryToInstall As String = Browse.TextBox.Text

Private Sub InstallMods()

    If HPV2.Checked = True Then
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\gui\Scaleform\FragCorrelation.swf", (DirectoryToInstall) & "\res_mods\0.9.4\gui\scaleform\FragCorrelation.swf")
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\scripts\client\mods\TeamHPPools.pyc", (DirectoryToInstall) & "\res_mods\0.9.4\scripts\client\mods\TeamHPPools.pyc")
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\scripts\client\gui\scaleform\daapi\view\lobby\settings\settingswindow.pyc", (DirectoryToInstall) & "\res_mods\0.9.4\scripts\client\gui\scaleform\daapi\view\lobby\settings\settingswindow.pyc")
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\ModSettings\ModSettings.cfg", (DirectoryToInstall) & "\res_mods\ModSettings\ModSettings.cfg")
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\ModSettings\MultilinedTankCarousel.cfg", (DirectoryToInstall) & "\res_mods\ModSettings\MultilinedTankCarousel.cfg")
                My.Computer.FileSystem.MoveFile(appData & "\Svatekl3\Svatekl2\Team HP Idicator\V3\ModSettings\Team HP Pools and Healthbar.cfg", (DirectoryToInstall) & "\res_mods\ModSettings\Team HP Pools and Healthbar.cfg")
            End If

End Sub

(这只是一个示例代码...还有更多内容:P)它必须移动大约200个文件,具体取决于该人是否检查复选标记以移动这些文件。

这就是我的背景工作者的样子:

Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
    Dim DirectoryToInstall As String = Label4.Text

    DeleteTemp()

    CleanMods()

    MoveZip()

    MyExtract()


    CreateDirs()

    InstallMods()

    DeleteTemp()

    Finish.StartPosition = FormStartPosition.CenterScreen
    Finish.Show()
    Me.Hide()
End Sub

它非常不言自明......程序创建的DeleteTemp()删除文件是不需要的。

CleanMods()删除用户选择的游戏目录中的文件,以确保他使用安装程序安装的所有mod都能正常工作。

The MoveZip()将zip文件从资源移动到appData。

MyExtract()提取这些文件

CreateDirs()为文件创建文件夹

InstallMods()将文件移动到正确的目录

我再次DeleteTemp() ......

我解释了这一切,所以你知道程序应该做什么......

现在回到我的问题......如果我使用UI线程,一切都很完美!它删除所有文件,安装所有文件,提取所有文件等。

唯一的缺点是UI被冻结了。

现在我想到了使用辅助线程并没有真正解决问题:(

所以我决定给后台工作者一个镜头......我将所有代码放在Backgroundworker中并运行程序。

每次程序到达安装文件的部分时,它都会告诉我"这些文件已经存在" ..

但与此同时我正在观看我的文件夹,看起来后台工作者的目录错误...因为它没有将文件安装到目录中(也没有对该目录进行任何更改)在所有)

我的意思是......让我们说Dim DirectoryToInstall As String = TextBox1.Text

TextBoxt1.Text =无论用户在文件浏览器中选择什么。

例如,我选择文件夹"桌面" ...

因此,将文件安装到桌面上的程序INSTEAD会将它们安装到其他文件夹中。

为什么会这样?

如果我使用UI线程..没有问题。

我听说backgroundworker,因为它使用不同的线程,无法从UI线程接收任何信息。

所以我不得不将这些信息发送给我的背景工作者,但是怎么样?

更新:

看起来后台工作者不想运行此代码:

Private Sub CleanMods()


        Dim appData As String = GetFolderPath(SpecialFolder.ApplicationData)
        If CleanOutFolders.RadioButton1.Checked = True Then

            Try
                Dim path As String = (DirectoryToInstall) & "\res_mods"
                My.Computer.FileSystem.DeleteDirectory(path, FileIO.RecycleOption.DeletePermanently, FileIO.UICancelOption.DoNothing)
            Catch
                MessageBox.Show("res_mods not found!")
            End Try

            Try
                FileSystem.Kill((DirectoryToInstall) & "\res\audio\xvm.fsb")
                FileSystem.Kill((DirectoryToInstall) & "\res\audio\xvm.fev")
                FileSystem.Kill((DirectoryToInstall) & "\res\audio\voice.fsb")
                If File.Exists((DirectoryToInstall) & "\res\audio\voice.fev") Then
                    FileSystem.Kill((DirectoryToInstall) & "\res\audio\voice.fev")
                End If
            Catch
            End Try
        End If
    End Sub

1 个答案:

答案 0 :(得分:1)

目前,您正在访问后台工作程序中的UI,您不应该访问它 - 它不在UI线程上运行。

One overload of BackgroundWorker.RunWorkerAsync有一个Object参数,这是DoWorkEventArgs.Argument可用的值 - 这是将“输入”传达给任务的最佳方式。如果你只是传递一个值(例如一个字符串),你可以直接这样做;否则,创建一个类来将所有信息包装在一个对象中。

此外,您的最后三行也访问了UI,因此它们应该位于BackgroundWorker.RunWorkerCompleted事件的处理程序中,该事件将在UI线程上执行。