【问题标题】:Run a task for two seconds without blocking UI在不阻塞 UI 的情况下运行任务两秒钟
【发布时间】:2017-06-22 10:35:16
【问题描述】:

我正在编写一个与 CAN 总线交互的 VB.Net 应用程序,以控制其上的一些电机。 使用 CAN 总线,我可以在正常和反向模式下打开和关闭每个电机,并读取它们的电流消耗。 我为每个电机实现了两个复选框,使其正常运行或反向运行,以及一个显示实际电流消耗的文本框,这实际上是有效的。 现在我想做的是自动化一些测试,例如:

  • 在每个方向上运行每个电机两秒钟并记录其消耗以查看值是否正确。

为此,我创建了一个 TestMotor 类,我在其中发送两个按钮的参考,这些按钮可以正常打开或反转每个电机。每个测试类代表每个电机的测试,所以如果我有 4 个电机,我将创建 4 个 TestMotor 对象,为它们提供两个复选框,为该电机供电。

最后,TestMotor 类有一个 executeTest,它主要通过选中和取消选中复选框在每个方向上运行电机两秒钟。 这两秒延迟了它们之间的延迟。

我的问题是,如果我直接在主线程上运行这些测试,Thread.sleep 会阻塞 UI 线程,但是如果我创建一个线程然后执行这些测试,那么它们会同时执行。

你会如何解决这个问题?我一直在尝试使用异步任务、计时器,现在我打算尝试一些信号量或其他东西,但是关于解决这个问题的最佳方法的一点帮助会很棒。

一些代码:

在主类中

for each test in test
    test.executeTest()
end for

TestMotor 类

public sub executeTest()
    ckNormal.checked = true
    Thread.sleep(2000)
    ckNormal.checked = false
    ckReverse.checked = true
    Thread.sleep(2000)
    ckReverse.checked = false
end sub

谢谢!

【问题讨论】:

    标签: .net vb.net multithreading semaphore


    【解决方案1】:

    不要使用Thread.sleep() 使用Task.Delay()

    @StephenCleary THIS THREAD 的回复。

    当你想阻塞当前线程时使用Thread.Sleep。

    当你想要一个逻辑延迟而不阻塞时使用Task.Delay 当前线程。

    【讨论】:

    • 如果我在主线程中使用Task.Delay,它只是关闭程序,不工作,我认为这是一个好主意但是使用一个新线程,然后这里我有问题了解如何使主要威胁等待执行新测试,直到实际尚未完成。
    • @rul3s :您是否等待延迟? Await Task.Delay(2000)
    • 是的 rul32 按照@VisualVincent 所说的那样做,将其作为异步任务进行威胁
    【解决方案2】:

    是的,我也尝试过,但是如果我使用异步任务执行 Task.Delay,问题是同时尝试了正常模式和反向模式。最后我做到了:

    Private Sub autocheck_btStart_Click(sender As Object, e As EventArgs) Handles autocheck_btStart.Click
        If Not currentlyTesting Then
            currentlyTesting = True
            principal.setRecording(True, ecu)
            Dim t As Task = Task.Run(Sub()
                                         startTesting()
                                     End Sub)
            principal.setRecording(False, ecu)
            currentlyTesting = False
        End If
    End Sub
    
    Public Sub startTesting()
        For Each test In tests
            tbDebug.AppendText("Testing motor " + test.getName() + Environment.NewLine)
            test.executeTest()
        Next
        showResults()
    End Sub
    
    Public Sub executeTest()
        isTesting = True
        ckNormal.Checked = True
        Thread.Sleep(2000)
        ckNormal.Checked = False
        Thread.Sleep(200)
        ckReverse.Checked = True
        Thread.Sleep(2000)
        ckReverse.Checked = False
        Thread.Sleep(200)
        isTesting = False
    End Sub
    

    谢谢你的建议!!

    【讨论】:

      猜你喜欢
      • 2014-04-05
      • 2022-07-12
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      相关资源
      最近更新 更多