【问题标题】:How to put this function inside a separate thread如何将此函数放在单独的线程中
【发布时间】:2012-11-28 11:07:00
【问题描述】:

我的表单需要一点(或很大)帮助:我需要在单独的线程中使用“组织函数”区域内的所有内容。

我在表单的“开始按钮”区域中按下一个按钮来调用“组织功能”子程序的第一个子程序;第一个子调用第二个子,第二个子调用第三个子。

我尝试自己将第三个 sub 添加到单独的线程中,然后使用第二个 sub 将参数传递给线程,但我所做的一切都是错误的。

有人可以帮我做吗?

PS:我已经删除了这个表格中不重要的部分,以便您更好地检查。

感谢您的阅读。

Public Class Form1


#Region "Declarations"

        ' MediaInfo
        Dim MI As MediaInfo

        ' Thread
        Dim paused As Boolean = False

        ' Others
        Dim NameOfDirectory As String = Nothing
        Dim aFile As FileInfo

#End Region



    'thread
    Dim t As New Thread(AddressOf ThreadProc)

    Public Sub ThreadProc()
        ' Aqui debería ir  todo el sub de "organize function", bueno... son 3 subs!
        If paused = True Then MsgBox("THREAD PAUSADO")
    End Sub



#Region "Properties"
...
#End Region

#Region "Load / Close"
...
#End Region

#Region "Get Total files Function"
...
#End Region

#Region "Option checkboxes"
...
#End Region

#Region "Folder buttons"
...
#End Region

#Region "Append text function"
...
#End Region





#Region "Action buttons"

   ' pause button
    Private Sub pause_button_Click(sender As Object, e As EventArgs) Handles pause_button.Click
        paused = True
    End Sub

    ' start button
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles start_button.Click

              t.Start()

                    ' Organization process
                    NameOfDirectory = userSelectedFolderPath
                    MediaInfo(NameOfDirectory)

        End Sub

#End region





#Region "Organize function"

        Public Sub MediaInfo(Directory)
            Dim MyDirectory As DirectoryInfo
            MyDirectory = New DirectoryInfo(NameOfDirectory)
            MediaInfoWorkWithDirectory(MyDirectory)
        End Sub

        Public Sub MediaInfoWorkWithDirectory(ByVal aDir As DirectoryInfo)
            Dim nextDir As DirectoryInfo
            MediaInfoWorkWithFilesInDir(aDir)
            For Each nextDir In aDir.GetDirectories
                Using writer As StreamWriter = New StreamWriter(aDir.FullName & "\" & nextDir.Name & "\" & nextDir.Name & ".m3u", False, System.Text.Encoding.UTF8)
                    'overwrite existing playlist
                End Using
                MediaInfoWorkWithDirectory(nextDir)
            Next
        End Sub

        Public Sub MediaInfoWorkWithFilesInDir(ByVal aDir As DirectoryInfo)

            Dim aFile As FileInfo





            For Each aFile In aDir.GetFiles()

               ' hacer cosas con aFile ...

            Next

        End Sub

#End Region



End Class

【问题讨论】:

  • 您到底想达到什么目的?代码看起来很乱,可能是因为它是通过大量的代码 sn-ps 和 SO 答案拼凑在一起的,而对一切工作原理没有深入了解。
  • 你好,是的,我是初学者,我知道如何制作一个 BASIC 后台工作人员,但我需要在一个后台工作人员中混合 3 个潜艇,我迷路了,谢谢你的评论......
  • 感谢您是新手,但您正试图以一种糟糕的方式“学习”。如果你花几周时间读一本像样的书,你就不会遇到所有这些问题。

标签: vb.net multithreading visual-studio backgroundworker


【解决方案1】:

有一个名为 BackgroundWorker 的 Windows 窗体组件,专门设计用于将长时间运行的任务从 UI 线程卸载到后台线程,从而使您的窗体美观且响应迅速。

BackgroundWorker 组件有一个名为 DoWork 的事件,用于在单独的线程上执行代码。将 BackgroundWorker 组件拖到表单上,然后执行以下操作:

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles start_button.Click
    NameOfDirectory = userSelectedFolderPath
    backgroundWorker1.RunWorkerAsync(NameOfDirectory)
End Sub

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim directoryName as string = e.Argument

    MediaInfo(directoryName)
End Sub

MSDN BackgroundWorker 页面和Code Project 上的示例可能有用。

HTH

【讨论】:

  • 好的,我解决了这个问题:“e As DoWorkEventArgs”但是 bakgroundworker 什么都不做......
  • 你是通过设计器添加后台worker,并选择DoWork事件,还是直接复制上面的sub?因为 e 肯定应该被定义。它应该如下所示: Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork End Sub
  • 道歉 Elektro 黑客,我通常不会在 VB 中编写代码并且方法签名错误。我已经用正确的 VB 签名更新了我的答案。
【解决方案2】:

大约有 5 打方法可以解决这个问题。我将只展示其中的 3 个:

Public Class Form1

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    ' fire and forget:
    Task.Run(Sub() FooA()).ContinueWith(Sub() FooB()).ContinueWith(Sub() FooC())
    Console.WriteLine("Button1 done")

End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

    ' fire and forget:
    Task.Run(Sub()
                 FooA()
                 FooB()
                 FooC()
             End Sub)
    Console.WriteLine("Button2 done")

End Sub

Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

    ' wait but dont block:
    Await Task.Run(Sub()
                       FooA()
                       FooB()
                       FooC()
                   End Sub)
    Console.WriteLine("Button3 done")

End Sub

Private Sub FooA()
    Threading.Thread.Sleep(1000)
    Console.WriteLine("A")
End Sub

Private Sub FooB()
    Threading.Thread.Sleep(1000)
    Console.WriteLine("B")
End Sub

Private Sub FooC()
    Threading.Thread.Sleep(1000)
    Console.WriteLine("C")
End Sub

End Class

我建议使用 Await 的那个(如果 FW 4.x 和 VS2012 不是问题)。

【讨论】:

  • 我非常感谢您的帮助,但我什么都不懂...您能告诉我“任务”应该是什么吗?是的,我正在使用 FW4.5 和 VS2012,谢谢你
  • @ElektroHacker:简单地说task 是一个轻量级的thread。它可能在本机 (Windows) 线程上运行,但不一定。最大的优势是,一个任务有一个result,你可以等待它。同步或异步(hronously) - 即阻塞或不阻塞调用线程。这使代码更易于阅读,因为您可以保持“线性”程序流。
猜你喜欢
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多