首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >背景线程减慢主UI线程visual

背景线程减慢主UI线程visual
EN

Stack Overflow用户
提问于 2020-09-14 23:11:15
回答 1查看 228关注 0票数 1

我想在图片盒中显示一个gif,在一个独立的线程和主线程上显示2秒。我正在运行一个定时器,它移动带有主线程上的图像的图片框。

为了进行测试,我创建了一个图片框并添加了相同的图像,我通过单击按钮启动后台线程。明显的错误或问题是,假定的背景线程减慢了主线程。

创建和实现线程似乎提供了两个选项: BackgroundWorker和Task.Run。

我看了这篇代码杂志的文章,它提供了比我所掌握的更多的选项:“守则”杂志文章

也看过本文不能将C#代码转换成VB是的,我使用了代码转换器:斯蒂芬·克利里

我的代码张贴在下面的背景线程,不需要张贴计时器滴答代码。

问我错过了什么,我做错了什么,或者这是不可能的?

代码语言:javascript
运行
复制
Private Sub myThreadMethod()
    'Await
    'Async
    Dim myThread As New Thread(AddressOf myThreadMethod)
    myThread.IsBackground = True

    myThread.Start()
    If Me.InvokeRequired = True Then
        Me.Invoke(Sub()
                      'PbT.Location = New Point(128, 132)
                      PbT.Left -= 1
                      PbT.Top += 2
                  End Sub)
        'If PbT.Bounds.IntersectsWith(btnBot.Bounds) Then
        'TextBox1.Invoke(Sub() TextBox1.Text =
    End If
    If PbT.Location.Y > 500 Then
        PbT.Invoke(Sub() PbT.Location = New Point(350, 230))
        Thread.Sleep(9000)
        myThread.Abort()
    End If

End Sub

问题的答案由克雷格添加并由James_Duh回答

代码语言:javascript
运行
复制
Public Class frmStart

Dim running As Boolean = False
Dim stopWatch As Stopwatch = New Stopwatch

Private Sub frmStart_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    Cursor.Clip = New Rectangle(Me.Location, Me.Size)
    btnLPad.Left = e.X
    btnCPad.Left = e.X + 28
    btnRPad.Left = e.X + 56
End Sub

Private Sub tmrMove_Tick(sender As Object, e As EventArgs) Handles tmrMove.Tick

    Static direction As New Point(0, 4)

    Static endTime As DateTime = DateTime.Now.AddYears(1)
    If DateTime.Now > endTime Then
        PbT.Visible = False
        endTime = DateTime.Now.AddYears(1)
    End If

    If _buttons.All(Function(x) x.Button.Visible = False) Then
        pbOne.Top = 300
        PbT.Visible = False
        tbAns.Visible = True

        stopWatch.Stop()
        Dim ts = stopWatch.Elapsed
        Dim elapsedTime = $"{ts.Minutes:0} Min {ts.Seconds:00} Sec"
        tbAns.Text = elapsedTime

        running = False
        direction = New Point(0, 4)

        tmrMove.Stop()
        MsgBox("You Win")
        stopWatch.Reset()
        '================
        tbAns.Visible = False
        ResetButtons()

    End If

    If pbOne.Bounds.IntersectsWith(btnLPad.Bounds) Then
        direction = New Point(-2, -3)
    End If
    If pbOne.Bounds.IntersectsWith(btnRight.Bounds) Then
        Static spC As Integer = 1
        spC += 1
        direction = If(spC Mod 2 = 0, New Point(-3, 2), New Point(-5, 1))
    End If

    If pbOne.Bounds.IntersectsWith(btnLeft.Bounds) Then
        direction = New Point(4, 2)
    End If

    If pbOne.Bounds.IntersectsWith(btnCPad.Bounds) Then
        direction = New Point(direction.X, -4)
    End If

    If pbOne.Bounds.IntersectsWith(btnRPad.Bounds) Then
        Static spA As Integer = 1
        spA += 1
        direction = If(spA Mod 2 = 0, New Point(1, -5), New Point(-3, -4))
    End If

    If pbOne.Bounds.IntersectsWith(btnTop.Bounds) Then
        Static spE As Integer = 1
        spE += 1
        direction = If(spE Mod 2 = 0, New Point(-3, 2), New Point(4, 2))
    End If

    If pbOne.Bounds.IntersectsWith(btnBot.Bounds) Then
        tmrMove.Stop()
        running = False
        pbOne.Top = 200
        PbT.Visible = False
        MsgBox("Press S to Start")
    End If

    pbOne.Left += direction.X
    pbOne.Top += direction.Y

    For Each x In _buttons
        If pbOne.Bounds.IntersectsWith(x.Button.Bounds) Then
            endTime = DateTime.Now.AddSeconds(2.0)
            x.Button.Visible = False
            x.Button.Location = New Point(350, -30)
            PbT.Location = New Point(x.Location.X + 20, 31)
            PbT.Visible = True
            direction = New Point(3, 3)
        End If
    Next
End Sub
Private Sub frmStart_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

    If running AndAlso e.KeyCode = Keys.P Then
        tmrMove.Stop()
    End If

    If e.KeyCode = Keys.S Then

        If Not running Then
            stopWatch.Start()
            running = True
        End If

        tmrMove.Interval = 1
        tmrMove.Start()

    End If

End Sub
Public Sub frmStart_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
    'Form Property KeyPreview needs to be set to True
    '=================================================

    If Asc(e.KeyChar) = 27 Then

        Const message As String = "YES" & "   Exit Program" + vbCrLf + vbNewLine + "NO" & "     Read Directions"
        Const caption As String = "Exit OR Return"

        Dim result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question)

        If result = DialogResult.Yes Then
            Application.Exit()
        ElseIf result = DialogResult.No Then
            frmInfo.Show()
            Close()
        End If
    End If

End Sub

Private _buttons As (Button As Button, Location As Point)() = Nothing

Private Sub frmStart_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    If _buttons Is Nothing Then
        _buttons =
        {
            (btnB1, New Point(29, 32)),
            (btnB2, New Point(110, 32)),
            (btnB3, New Point(191, 32)),
            (btnB4, New Point(272, 32)),
            (btnB5, New Point(353, 32)),
            (btnB6, New Point(434, 32)),
            (btnB7, New Point(515, 32)),
            (btnB8, New Point(596, 32)),
            (btnB9, New Point(677, 32))
        }
    End If
    ResetButtons()
End Sub

Private Sub ResetButtons()
    For Each x In _buttons
        x.Button.Visible = True
        x.Button.Location = x.Location
    Next
End Sub

端级

上面的代码来自于神秘,并修复了许多问题。请看他对秒表的评论和演奏。同时,这个游戏使用他的代码比以前快了70%。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-15 18:33:22

试图复制这个没有看到你的计时器滴答代码我自己写的

理解游戏设计的突破将有助于任何人试图遵循的步骤,需要显示的gif在X秒

首先,您需要将秒表集成到计时器中。

其次,您需要知道何时设置结束时间(以秒为单位)逻辑将要求在球IntersectsWith (砖块)时发生这种情况。

所以我们编写了一个叫做Fire的函数参见下面的代码

不需要每个砖块都有一个gif,所以现在我们需要将我们的一个和唯一的gif移动到正确的块上,让它运行X秒。我们还需要使gif可见,为什么您可能会问,如果启用和可见,它们会永远运行--只需要管理可见性就更容易了

您还需要计时器刻度方法中的代码,使gif在X秒后不可见

请原谅我缺少声明变量。

pbOne =球& btnB1 =砖块& PbT =带gif的图片框

代码语言:javascript
运行
复制
 Public Function Fire() As Integer
    'Set Stopwatch 5 sec in the future
    nT = CDbl(DateTime.Now.AddSeconds(5).ToString("ss"))
    Return CInt(nT)
End Function


Private Sub tmrMove_Tick(sender As Object, e As EventArgs) Handles tmrMove.Tick

    'nS is Rolling Time
    nS = CDbl(DateTime.Now.ToString("ss"))
    If nS > nT Then
        PbT.Visible = False
    End If

    If pbOne.Bounds.IntersectsWith(btnB1.Bounds) Then
        btnB1.BackColor = Color.Red
        btnB1.Visible = False
        Fire()
        Y = btnB1.Location.Y
        X = btnB1.Location.X
        PbT.Location = New Point(X + 20, Y)
        PbT.Visible = True
        btnB1.Location = New Point(350, -30)
        rndNUM = 8
    End If
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63892922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档