我应该如何修改此代码以适应异步行为?

时间:2019-04-24 03:48:33

标签: vb.net asynchronous async-await

我有一个按钮。如果按下按钮,我希望所有按钮都被禁用。然后我想做点事情。完成之后,我希望重新启用所有按钮。

简单吗?

这是代码

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

现在永远不会调用昏暗的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有效

3 个答案:

答案 0 :(得分:1)

尝试一下:

BookingRequests

答案 1 :(得分:0)

为什么要使用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

答案 2 :(得分:0)

这段代码做到了

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。如果是这样,为什么?那将是另一个问题。