【问题标题】:How should I modify this code to accomodate async behaviour?我应该如何修改此代码以适应异步行为?
【发布时间】:2019-04-26 00:44:51
【问题描述】:

我有一个按钮。如果按下按钮,我希望禁用所有按钮。然后我想做点什么。完成后,我希望重新启用所有按钮。

简单吧?

这里是代码

Public Sub startAndStopClickingButton(ByVal sender As Object, ByVal SomeSub As System.Action)
    startClickingButton(sender)
    SomeSub.Invoke()
    stopClickingButton(sender)
End Sub

然后我做

Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles cmdGroupRepeat.Click
    startAndStopClickingButton(sender, Sub()
                                           finRepeatOrdering() ' this one never end
                                           Dim b = 1
                                       End Sub)
End Sub

效果很好。 Startclickingbutton 被调用。然后我调用中间的任何 lambda。然后在它完成后(实际上从来没有),调用 stopclickingbutton 。很简单。

然后我改变了我的程序。 finRepeatOrdering 现在是 finRepeatOrderingAsync。

但是,我仍然想要相同的行为。我希望在按下 stopClickingButton 之前等待 finRepeatOrderingAsync 完成。

所以,我做到了

Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles cmdGroupRepeat.Click
    startAndStopClickingButton(sender, Async Sub()
                                           Await finRepeatOrderingAsync() ' this one never end
                                           Dim b = 1 'a breakpoint here
                                       End Sub)
End Sub

现在 dim b=1 永远不会被调用。但是,过早地调用了 stopClickingButton。怎么会?

我应该如何更改程序以使其正常工作?

我试过了

Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles cmdGroupRepeat.Click
    startAndStopClickingButton(sender, Async Function() As Task
                                           Await finRepeatOrderingAsync() ' this one never end
                                           Dim b = 1
                                       End Function)
End Sub

Public Async Function startAndStopClickingButton2(ByVal sender As Object, ByVal SomeSub As System.Func(Of Task)) As Task
    startClickingButton(sender)
    Await SomeSub.Invoke()
    stopClickingButton(sender)
End Function

我收到了编译器警告

严重性代码描述项目文件行抑制状态 警告 BC42359 从此异步函数返回的任务将被删除,其中的任何异常都将被忽略。考虑将其更改为 Async Sub,以便传播其异常。 nicehash2 H:\business\shared\Dropbox\vb.net\nicehashform.vb 60 活动

【问题讨论】:

    标签: vb.net asynchronous async-await


    【解决方案1】:

    试试这个:

    Public Async Function startAndStopClickingButton(ByVal sender As Object, ByVal SomeSub As System.Func(Of Task)) As Task
        startClickingButton(sender)
        Await SomeSub.Invoke()
        stopClickingButton(sender)
    End Function
    
    Private Async Sub Button2_Click_1(sender As Object, e As EventArgs) Handles cmdGroupRepeat.Click
        Await startAndStopClickingButton(sender, Async Function() As Task
                                               Await finRepeatOrderingAsync()
                                               Dim b = 1
                                           End Sub)
    End Sub
    

    【讨论】:

    • 我收到了编译器警告。
    • 什么编译器警告?
    • 我忘了。但是想想看。 startAndStopClickingButton 是一个返回任务的异步函数。应该期待吧?但不是。您只需调用异步函数而无需等待。
    【解决方案2】:

    你为什么使用invoke而不是Task.run?你可以试试;

    Public Async Sub startAndStopClickingButton(ByVal sender As Object, ByVal SomeSub As System.Action)
        startClickingButton(sender)
        Await Task.Run(SomeSub) 
        stopClickingButton(sender)
    End Sub
    

    【讨论】:

      【解决方案3】:

      这段代码做到了

      Private Async Sub RepeatTheWholeThing_Click_1(sender As Object, e As EventArgs) Handles cmdGroupRepeat.Click
          Await startAndStopClickingButton2(sender, Async Function() As Task
                                                        Await finRepeatOrderingAsync() ' this one never end
                                                        Dim b = 1
                                                    End Function)
      End Sub
      
      Public Async Function startAndStopClickingButton2(ByVal sender As Object, ByVal SomeSub As System.Func(Of Task)) As Task
          startClickingButton(sender)
          Await SomeSub.Invoke()
          stopClickingButton(sender)
      End Function
      

      处理程序本身需要异步。然后 startAndStopClickingButton 也需要是异步的。与 Paulo 的回答唯一不同的是我等待 startAndStopClickingButton2。

      要了解它是如何工作的,我们需要看到 await 并没有真正阻塞。它返回给调用者。 Await SomeSub.Invoke() 完成后,事件处理程序将运行并执行 stopClickingButton(sender)

      如果有更好的解决方案。我想知道处理程序是否必须是异步的,或者 startAndStopClickingButton 是否真的需要更改。如果是这样,为什么?那将是另一个问题。

      【讨论】:

        猜你喜欢
        • 2022-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-20
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多