尝试在MVC应用中实现异步功能

时间:2019-03-18 16:55:54

标签: asp.net-mvc vb.net asynchronous async-await http-post

我不确定我会在正确的庄园中进行此操作,这是我的情况:

我有一个MVC网站,该网站具有发票视图,该视图包含一种形式,用户可以从下拉列表中选择功能,而从另一个下拉列表中选择年/月。单击“处理”按钮会触发发布到我的控制器中某个功能的消息。

此函数用于使用传递的数据执行存储过程并返回从存储过程@Output返回的'SUCCESS'或'FAIL'。

不幸的是,许多过程需要很长时间才能完成(有些过程可能需要25分钟),并且Post总是不变。

由于我并不十分担心存储过程返回SUCCESS或FAIL,因为存储过程将通过电子邮件发送结果或错误,因此我决定尝试调用异步函数并进行一些单击和忘记操作。

这就是我拥有的:

将按钮发布到InvoiceProcess函数的按钮单击代码的一部分

var postURL = '@Url.Content("~/Invoicing/InvoiceProcess")'

        $.ajax({
            url: postURL,
            type: "post",
            data: {
                ProcName: usp,
                User: '@Model.FJLogin',
                Email: '@Model.Email',
                ParamName : paramName,
                ParamValue: paramValue
            },
            success: function (r) {
                if (r == "SUCCESS") {
                    invoiceNotification.show({
                        title: "Process acknowledged",
                        message: 'The Procedure acknowledged it has started. It may take a while to run. Results will be emailed to you as soon as the process has completed.'
                    }, "success");
                } else {
                    invoiceNotification.show({
                        title: "Function Process Failed",
                        message: '<ul>' + r + '</ul>'
                    }, "error");
                }
                btnProc.prop("disabled", false);
            }
        });

控制器具有以下内容:

    <HttpPost>
        Function InvoiceProcess(ByVal ProcName As String, ByVal User As String, ByVal Email As String, ByVal ParamName As String, ByVal ParamValue As String) As String

            ' Problem - function is executing specified stored proc which can take a while to execute. (three of the procs typically takes 20-25mins). 
            ' If the stored proc takes too long the ajax call that triggers this post can timeout giving the user an error when in fact there was no error... the page just timed out. 
            ' Solution - have this method set a boolean Session variable (ProcName +'Triggered'). If it is false when this post method is called we asynchronously execute the required 
'stored proc, else the method simply returns a message informing user that this proc has been triggered and is still running.

            Dim mySessionName = ProcName & "Triggered"
            If IsNothing(Session(mySessionName)) Then Session(mySessionName) = False

            If Session(mySessionName) Then
                Return "ERROR: This procedure has been triggered and is still being processed. Please wait for result."
                Exit Function
            Else
                Dim logMsg As String = "The stored procedure " & ProcName & " was triggered by " & User & " - " & Email & " on " & Now().ToString & " with the following value '" & ParamValue & "' for the paramerter @" & ParamName & "."
                LogMsgToLogFile(logMsg, "InvoiceProcess", "InvoiceController")

                HostingEnvironment.QueueBackgroundWorkItem(Async Function(cancellationToken)
                                                               Await runStoredProcedure(ProcName, User, Email, ParamName, ParamValue)
                                                               Session(mySessionName) = False
                                                           End Function)

                Session(mySessionName) = True

                Return "SUCCESS"

            End If

        End Function '- Invoice Process


        Private Function runStoredProcedure(ByVal ProcName As String, ByVal User As String, ByVal Email As String, ByVal ParamName As String, ByVal ParamValue As String) As Task(Of Object)


            LogMsgToLogFile("Process triggered off")

            'Dim Result As String = DBFunctions.ExecuteStoredProc(ProcName, User, Email, ParamName, ParamValue)

            'Set up SqlConnection
            Dim strConnString As String = ConfigurationManager.ConnectionStrings("FADConn").ConnectionString
            Dim con As New SqlConnection(strConnString)
            Dim cmd As New SqlCommand With {
            .CommandType = Data.CommandType.Text
        }

            Dim SqlScript = "EXEC dbo." & ProcName & " @User = '" & User & "', @EmailAddress = '" & Email & "'"

            If ParamName <> "" Then
                SqlScript += ", @" & ParamName & " = " & ParamValue
            End If

            SqlScript += ";"

            cmd.CommandText = SqlScript
            cmd.Connection = con

            Try
                con.Open()
                cmd.ExecuteNonQuery()
                Return Nothing

            Catch ex As Exception
                Dim msg As String = "<li>" & ex.Message & "</li>"
                If Not IsNothing(ex.InnerException) Then
                    msg += "<ul><li>" & ex.InnerException.Message & "</li></ul>"
                End If
                LogExceptionToLogFile("DBFunctions", "ExecuteStoredProc", ex)
                Return Nothing
            Finally
                con.Close()
                con.Dispose()
            End Try

            LogMsgToLogFile("Process finished")

            'Return Nothing

        End Function ' runStoredProcedure

当运行LogMsgToLogFile函数完成时很好。

但是HostingEnvironment.QueueBackgroundWorkItem(异步函数(cancellationToken)  ... )无法运行。...runStoreProcedure函数内的LogMsgToLogFile均未运行。此函数中的任何断点都会被命中。直接从sql运行时,存储过程都很好。当我在不使用异步功能的情况下在Post Function中执行存储的proc的代码时,该网站的运行状况也很好。

任何帮助表示赞赏。

0 个答案:

没有答案