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

问题描述 投票:0回答:3

我有一个按钮。如果按下按钮,我想要禁用所有按钮。然后我想完成一些事情。完成后,我希望重新启用所有按钮。

简单吧?

这是代码

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

它工作正常。调用Startclicking按钮。然后我调用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 Active

vb.net asynchronous async-await
3个回答
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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.