Попытка реализовать Асинхронную функцию в приложении MVC - PullRequest
0 голосов
/ 18 марта 2019

Я не уверен, что пойду об этом в правильном поместье, вот мой сценарий:

У меня есть веб-сайт MVC, который имеет представление фактурирования, состоящее из формы, в которой пользователь выбирает функцию из раскрывающегося списка и год / месяц из другого раскрывающегося списка. Нажатие на кнопку «Процесс» запускает сообщение для функции в моем контроллере.

Эта функция использовала данные, переданные для выполнения хранимой процедуры, и возвращает либо «SUCCESS», либо «FAIL», которые возвращаются из хранимой процедуры @ Output.

К сожалению, многие из процедур занимают много времени (некоторые могут занимать 25 минут) и неизменны время ожидания сообщения.

Поскольку я не очень обеспокоен тем, что Stored Proc возвращает SUCCESS или FAIL, потому что Stored Proc отправит результаты по электронной почте или сообщение об ошибке, я решил попробовать вызвать асинхронную функцию и выполнить щелчок и забыть.

Вот что у меня есть:

часть кода для нажатия кнопки, которая отправляет сообщение в функцию 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) ... ) не запускается .... не выполняется ни один из LogMsgToLogFile в функции runStoreProcedure. Любые точки останова в этой функции когда-либо получают удар. Хранимые Procs все в порядке, когда запускаются непосредственно из SQL. Кроме того, с веб-сайта все работало нормально, когда у меня был код, выполняющий сохраненный процесс в функции Post без использования функции Async.

Любая помощь приветствуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...