【问题标题】:Waiting until threads finish before executing next step等到线程完成后再执行下一步
【发布时间】:2016-06-03 13:58:41
【问题描述】:

我最多可以同时运行两个线程。在执行下一步之前如何等待这些线程完成?

如果我不等待它们,我会在检查值时收到 NullReferenceException,因为由于线程仍在运行,它们尚未设置。

【问题讨论】:

  • 您是否考虑过使用 Async / Await 或任务并行库来代替原始线程?
  • 你能提供一篇关于他们的文章的链接吗?
  • 这是来自微软msdn.microsoft.com/en-us/library/hh194766(v=vs.110).aspx的一个很好的例子
  • 谢谢!会阅读,如果我有任何问题会回复。 :)

标签: vb.net multithreading winforms


【解决方案1】:

我会在这方面使用 Async / Await 模式。它为您提供出色的流量控制,并且不会锁定您的 UI。

这是来自MSDN的一个很好的例子:

Public Class Form1
    Public Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim tasks As New List(Of Task)()
        tasks.Add(Task.Run(addressof Task1))
        tasks.Add(Task.Run(addressof Task2))
        Await Task.WhenAll(tasks)

        MsgBox("Done!")
    End Sub

    Private Async Function Task1() As Task 'Takes 5 seconds to complete
        'Do some long running operating here. Task.Delay simulates the work, don't use it in your real code
        Await Task.Delay(5000)
    End Function

    Private Async Function Task2() As Task 'Takes 10 seconds to complete
        'Do some long running operating here. Task.Delay simulates the work, don't use it in your real code
        Await Task.Delay(10000)
    End Function
End Class

基本思想是创建一个Task 数组(这些也可以指向返回Task 的函数)。当您调用Task.WhenAll 时,这会将包装在任务对象中的“线程”排队,这将执行数组中的所有任务并在它们全部完成后继续。之后的代码将在每个任务完成后运行,但不会阻塞 UI 线程。

【讨论】:

  • 我稍微修改了这个例子,在结果上实际使用了Await。 MSDN 示例更多的是关于任务而不是异步/等待,但它们非常兼容。
  • 谢谢!我注意到的一件事是异步函数返回一个值。在示例的异步函数中,我改为使用一个 sub 调用另一个不返回任何值的 sub。我该如何解释?
  • 我对我的示例进行了一些更新,以更好地展示我认为您正在尝试做的事情。如果您有一些不返回值的线程代码,请使用Task,如果需要返回值,请使用Task(of ReturnType)Await,结果与dim result as integer = Await SomeFunctionThatReturnsATaskOfInteger() 相同。
  • Delay不是Task的成员,能帮忙吗?
【解决方案2】:

如果你调用 join 主线程将等待另一个线程完成。我认为下面的代码可以很好地理解这个想法。

Sub Main()
        thread = New System.Threading.Thread(AddressOf countup)
        thread.Start()
        thread2 = New System.Threading.Thread(AddressOf countup2)
        thread2.Start()
        thread.Join() 'wait thread to finish
        thread2.Join()  'wait thread2 to finish
        Console.WriteLine("All finished ")
        Console.ReadKey()
    End Sub

查看链接: General; WinForms

【讨论】:

  • 可能适用于控制台应用程序,但在 Winforms 应用程序中使用它会使 UI 冻结。
  • 如果 OP 想要一个特定于平台的解决方案,他应该用平台标记问题。
  • @ruirodrigues1971 那个网站上的例子太可怕了。它实际上指示您使用CheckForIllegalCrossThreadCalls = False 禁用线程安全检查。我不建议任何人效仿这个例子。
  • 您提供的链接似乎很旧。这与 OP 的问题无关,我相信他知道如何使用线程。应该从不CheckForIllegalCrossThreadCalls设置为False。
  • @HighMans : 如果你在一个新线程中开始并加入你的线程,你不会遇到冻结 UI 的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 2017-02-21
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多