多线程不同时移动对象

时间:2022-09-23 21:00:34

I'm trying to get a thread to move two Picture Boxes at the same time but that doesn't happen, the first one starts moving then when that is done the second one starts. I don't know how to make them move at the same time.

我试图获得一个线程同时移动两个图片框,但这不会发生,第一个开始移动然后当完成第二个开始。我不知道如何让它们同时移动。

Here's the code:

这是代码:

Imports System.Threading
Public Class Form1
Private picuser As New PictureBox()
Private y As Integer
Private thread1 As Thread
Private thread2 As Thread
Private thread3 As Thread
Private thread4 As Thread

Public Sub enemy1()
    picUser = New System.Windows.Forms.PictureBox()
    picUser.Visible = True
    picUser.Size = New System.Drawing.Size(32, 32)
    picuser.Location = New System.Drawing.Point(100, 100)
    picuser.BackColor = Color.Purple
    Dim e As New AddControlEventArgs(picuser)

    ' Create EventHandler
    Dim ehnd As New EventHandler(AddressOf AddControl)

    ' Invoke EventHandler with EventArgs (don't need sender as of now)
    thread1 = New Thread(Sub() Me.Invoke(ehnd, Nothing, e))
    thread1.Start()
End Sub

Public Sub enemy2()
    picuser = New System.Windows.Forms.PictureBox()
    picuser.Visible = True
    picuser.Size = New System.Drawing.Size(32, 32)
    picuser.Location = New System.Drawing.Point(150, 100)
    picuser.BackColor = Color.Red
    Dim e As New AddControlEventArgs(picuser)

    ' Create EventHandler
    Dim ehnd As New EventHandler(AddressOf AddControl)

    ' Invoke EventHandler with EventArgs (don't need sender as of now)
    thread2 = New Thread(Sub() Me.Invoke(ehnd, Nothing, e))
    thread2.Start()
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    thread3 = New Thread(AddressOf enemy1)
    thread4 = New Thread(AddressOf enemy2)
    thread3.Start()
    thread4.Start()
End Sub

Private Sub mover(ByVal x As PictureBox)
    For z = 0 To 10
        x.Location = New Point(x.Location.X, x.Location.Y + 10)
        Threading.Thread.Sleep(100)
        Me.Refresh()
    Next
End Sub


Public Class AddControlEventArgs : Inherits EventArgs
    Public Sub New(p_control As Control)
        m_control = p_control
    End Sub
    Private m_control As Control
    Public ReadOnly Property Control As Control
        Get
            Return m_control
        End Get
    End Property
End Class

Private Sub AddControl(sender As Object, e As EventArgs)
    ' Cast EventArgs to your custom EventArgs
    Dim ec As AddControlEventArgs = DirectCast(e, AddControlEventArgs)
    Me.Controls.Add(ec.Control)
    Call mover(ec.Control)
End Sub
End Class

1 个解决方案

#1


2  

Use multithreading in a game only if you have heavy calculations to perform, that you want to distribute on the different CPU cores. Otherwise just use a game loop. Calculate the actual state of the game and positions of the objects depending on the current game time. Then update the UI and repeat these two steps until the user stops the game.

只有在要执行大量计算时,才要在游戏中使用多线程,并且要在不同的CPU核心上进行分发。否则只需使用游戏循环。根据当前游戏时间计算游戏的实际状态和对象的位置。然后更新UI并重复这两个步骤,直到用户停止游戏。

Using multithreading in order to update the UI won't work, since only one thread at a time can access the UI. To be more precise, only the UI thread (the thread the application is started in) can do it. Therefore the other threads have to call Invoke in order to let the UI thread update the UI.

使用多线程来更新UI将无法工作,因为一次只有一个线程可以访问UI。更确切地说,只有UI线程(应用程序启动的线程)可以执行此操作。因此,其他线程必须调用Invoke才能让UI线程更新UI。

Complicated calculations like artificial intelligence and physical simulations might still require multithreading. Here I see two possibilities:

人工智能和物理模拟等复杂计算可能仍需要多线程。在这里我看到两种可能性:

  1. The game loop starts several threads at each game loop and waits until they are all finished and then goes on with updating the UI.

    游戏循环在每个游戏循环中开始几个线程并等待它们全部完成然后继续更新UI。

  2. The threads run independently and update the game status continuously. The game loop repeatedly reads the game status and updates the UI accordingly. Here you need to lock the game status (the common resource) when accessing it. Keep the lock times short, i.e. do a substantial amount of work, then lock, update, unlock and go on with the calculation. It is probably a good idea to split the game status into several logical parts that can be locked individually. This reduces the chances of lock conflicts. All threads that have to access several resources must access them in the same order. This helps avoiding dead locks.

    线程独立运行并持续更新游戏状态。游戏循环重复读取游戏状态并相应地更新UI。在这里,您需要在访问时锁定游戏状态(公共资源)。保持锁定时间短,即做大量工作,然后锁定,更新,解锁并继续计算。将游戏状态分成几个可以单独锁定的逻辑部分可能是个好主意。这减少了锁定冲突的可能性。必须访问多个资源的所有线程必须以相同的顺序访问它们。这有助于避免死锁。

#1


2  

Use multithreading in a game only if you have heavy calculations to perform, that you want to distribute on the different CPU cores. Otherwise just use a game loop. Calculate the actual state of the game and positions of the objects depending on the current game time. Then update the UI and repeat these two steps until the user stops the game.

只有在要执行大量计算时,才要在游戏中使用多线程,并且要在不同的CPU核心上进行分发。否则只需使用游戏循环。根据当前游戏时间计算游戏的实际状态和对象的位置。然后更新UI并重复这两个步骤,直到用户停止游戏。

Using multithreading in order to update the UI won't work, since only one thread at a time can access the UI. To be more precise, only the UI thread (the thread the application is started in) can do it. Therefore the other threads have to call Invoke in order to let the UI thread update the UI.

使用多线程来更新UI将无法工作,因为一次只有一个线程可以访问UI。更确切地说,只有UI线程(应用程序启动的线程)可以执行此操作。因此,其他线程必须调用Invoke才能让UI线程更新UI。

Complicated calculations like artificial intelligence and physical simulations might still require multithreading. Here I see two possibilities:

人工智能和物理模拟等复杂计算可能仍需要多线程。在这里我看到两种可能性:

  1. The game loop starts several threads at each game loop and waits until they are all finished and then goes on with updating the UI.

    游戏循环在每个游戏循环中开始几个线程并等待它们全部完成然后继续更新UI。

  2. The threads run independently and update the game status continuously. The game loop repeatedly reads the game status and updates the UI accordingly. Here you need to lock the game status (the common resource) when accessing it. Keep the lock times short, i.e. do a substantial amount of work, then lock, update, unlock and go on with the calculation. It is probably a good idea to split the game status into several logical parts that can be locked individually. This reduces the chances of lock conflicts. All threads that have to access several resources must access them in the same order. This helps avoiding dead locks.

    线程独立运行并持续更新游戏状态。游戏循环重复读取游戏状态并相应地更新UI。在这里,您需要在访问时锁定游戏状态(公共资源)。保持锁定时间短,即做大量工作,然后锁定,更新,解锁并继续计算。将游戏状态分成几个可以单独锁定的逻辑部分可能是个好主意。这减少了锁定冲突的可能性。必须访问多个资源的所有线程必须以相同的顺序访问它们。这有助于避免死锁。