使事件函数等到代码隐藏中的UpdatePanel异步回发完成

问题描述

我有一个WebForm,其中有一个UpdatePanel更新数据值。我下面还有一个按钮,用于调用CodeBehind中的函数,该函数会将UpdatePanel中的值用作值。

到目前为止,代码可以正常运行,但是如果我Trigger对面板进行更新,然后快速单击按钮(如果操作足够快),则可能会导致运行时错误,因为执行了Click事件比UpdatePanel更快,并且在异步操作之前完成。

我尝试在函数顶部添加updatePanel.Update(),但是显然,这是在开始一个新过程,而不是强制等待现有过程。

如何在后面的代码中让我的函数等待异步任务完成?

由UpdatePanel触发的异步功能(将hfDeleteAppID的值设置为1)

    Protected Sub btn_A1_Sub_Click(sender As Object,e As EventArgs) Handles btn_A1_Sub.Click
        If btn_A1_Sub.CssClass = "fas fa-lg fa-times-circle" Then
            hfDeleteAppID.Value = 1
        Else
            applicationTransactions.saveUserApplication(Context.User.Identity.GetUserId(),1)
            dgYourApps.DataBind()
        End If
    End Sub

正在调用函数(需要使用hfDeleteAppID的值)

    Protected Sub App_Delete(sender As Object,e As EventArgs)
        upApplications.Update()

        Dim appID As Double = hfDeleteAppID.Value

        applicationTransactions.deleteApplication(Context.User.Identity.GetUserId(),appID)
        dgYourApps.DataBind()
    End Sub

解决方法

声明一个TaskCompletionSource字段,实例化并在Delete处理程序中等待它,必须将其更改为async

Dim tcs As TaskCompletionSource(Of Boolean)
...

Protected Async Sub App_Delete(sender As Object,e As EventArgs)
    tcs = new TaskCompletionSource(Of Boolean)

    upApplications.Update()
    
    'Wait until btn_A1_Sub_Click has finished
    await tcs.Task

    Dim appID As Double = hfDeleteAppID.Value

    applicationTransactions.deleteApplication(Context.User.Identity.GetUserId(),appID)
    dgYourApps.DataBind()
End Sub

在按钮单击处理程序中设置TCS的结果:

 Protected Sub btn_A1_Sub_Click(sender As Object,e As EventArgs) Handles btn_A1_Sub.Click
        If btn_A1_Sub.CssClass = "fas fa-lg fa-times-circle" Then
            hfDeleteAppID.Value = 1
        Else
            applicationTransactions.saveUserApplication(Context.User.Identity.GetUserId(),1)
            dgYourApps.DataBind()
        End If
        'Set the tcs to completed
        'Do some checks her and set result to false in case of error e.g.
        If tcs IsNot Nothing Then
           tcs.SetResult(True)
        End If
    End Sub

您可以肯定地将其声明为double并直接设置hfDeleteAppID的结果,而不是使用boolean类型的TCS。