【问题标题】:How to Implement Async - Await Function如何实现 Async - Await 函数
【发布时间】:2022-01-19 03:05:40
【问题描述】:

我正在尝试实现一个等待integer 返回值更新的串行端口接口。出于学习目的,我有一个 Async 函数从具有随机时间延迟的过程函数返回一个 integer。我包括了我在 cmets 中看到的错误。该函数似乎没有返回Integer,也没有GetAwaiter。

Private Sub btnSubMain_Click(sender As Object, e As EventArgs) Handles btnSubMain.Click
    Dim Answer As Integer
    Answer = SomeInteger() 'Value of type 'Task(of Integer)' cannot be converted to 'Integer'
End Sub

Public Async Function SomeInteger() As Task(Of Integer)
    Dim exampleInteger As Integer = Await AwaitedprocessAsync()  'Await requires that type 'Integer" 
    '                                                             have a suitable GetAwaiter method
    Return exampleInteger
End Function

Function AwaitedprocessAsync() As Integer
    Dim timeout As Integer = CInt(Rnd() * 100)
    Thread.Sleep(timeout)
    Return 34  'return some test integer
End Function

【问题讨论】:

  • 您的 AwaitedprocessAsync 方法需要返回 Task 才能等待。另外,请考虑使用Await Task.Delay(timeout) 而不是Thread.Sleep(timeout)。
  • @RelicCoder - SerialPort 有一个在收到数据时触发的事件,所以我不明白你为什么这样做。

标签: vb.net asynchronous async-await task-parallel-library


【解决方案1】:

我猜你想使用 Async / Await 的原因是在不阻塞 UI 的情况下执行异步处理。但是您设置它的方式看起来无论如何都会阻止用户界面。这是一个示例,它演示了如何在不阻塞和阻塞的情况下调用方法

Private Async Sub btnSubMain_Click(sender As Object, e As EventArgs) Handles btnSubMain.Click
    Dim answer As Integer
    Try
        btnSubMain.Enabled = False
        ' async call, UI continues to run
        answer = Await SomeIntegerAsync()
    Finally
        btnSubMain.Enabled = True
    End Try
    MessageBox.Show(answer.ToString())

    Try
        btnSubMain.Enabled = False
        ' synchronous call, UI is blocked
        answer = SomeInteger()
    Finally
        btnSubMain.Enabled = True
    End Try
    MessageBox.Show(answer.ToString())
End Sub

Function SomeIntegerAsync() As Task(Of Integer)
    Return Task.Run(AddressOf SomeInteger)
End Function

Function SomeInteger() As Integer
    Thread.Sleep(5000)
    Return 34
End Function

首先要注意的是UI事件处理程序被标记为Async,所以等待是在那个方法中完成的。大多数人都清楚,您的意图是在不阻塞 UI 的情况下允许某些事情发生。由于它是这样标记的,它必须包含Await。我写了两个函数,一个返回一个任务并且名称中有 Async,另一个只返回整数,名称中没有 Async。

我在按钮点击处理程序中都调用了。第一次调用将允许 UI 在调用函数时平稳运行。您可以通过在单击后移动窗口来检查。第二个直接调用函数并阻塞UI。这是您可以遵循的基本设计。

您可以使用Task.Delay 对您的问题注释进行评论,但我认为休眠线程是模拟长时间运行的代码的好方法,您不想阻塞用户界面,因此作为演示是有意义的。

【讨论】:

  • Re Sleep vs Task.Delay 我认为这部分取决于你想要什么。如果要模拟需要时间才能完成的异步操作,Await Task.Delay 更合适。如果你想模拟当前代码需要时间来完成,那么你可能更喜欢Sleep,特别是如果代码还没有在Async上下文中,你可以Await。
猜你喜欢
  • 2016-02-18
  • 2020-08-01
  • 2018-01-21
  • 2021-08-06
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多