Запуск кода После Response.End() и альтернативы для него

#asp.net #vb.net #webforms

Вопрос:

Я экспортирую код в файл csv, и процесс завершается с Response.End (), как и ожидалось, и процедура отправки почты в предложении Finally никогда не выполняется. Мне нужно запустить SendEmail() после ответа.Заканчиваю и ищу предложения. Если просто удалить ответ.Конец, тогда файл csv никогда не создается.

  Protected Sub ExportExcel(ByVal Vendor As String)
    Dim MyConnection As SqlConnection
    MyConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("BusOpsConnectionString").ConnectionString)
    Dim cmd As New SqlCommand("p_BPOTracker_ClosedReport", MyConnection)
    With cmd
        .CommandType = CommandType.StoredProcedure

        cmd.Parameters.AddWithValue("@Vendor", SqlDbType.VarChar).Value = Vendor
        cmd.Parameters.AddWithValue("@IssueStatus", SqlDbType.VarChar).Value = "Closed"

    End With

    Dim da As New SqlDataAdapter(cmd)
    Dim myDataTable As DataTable = New DataTable()
    da.Fill(myDataTable)

    Dim FileDate As String = Replace(FormatDateTime(Now(), DateFormat.ShortDate), "/", "")
    Dim attachmentName As String = "BPOTracker_Closed_Report_" amp; Vendor amp; "_" amp; FileDate amp; "_.csv"

    Try
        MyConnection.Open()
        Response.Clear()
        Response.ClearHeaders()
        Dim writer As New CsvWriter(Response.OutputStream, ","c, Encoding.Default)
        writer.WriteAll(myDataTable, True)
        writer.Close()

        Response.AddHeader("Content-Disposition", "attachment;filename=" amp; attachmentName)
        Response.ContentType = "application/vnd.ms-excel"
        Response.End()

    Finally

        If MyConnection.State <> ConnectionState.Closed Then MyConnection.Close()
        MyConnection.Dispose()
        MyConnection = Nothing
        myDataTable.Dispose()
        myDataTable = Nothing

        Thread.Sleep(3000)
        SendEmail(Vendor, attachmentName)

    End Try

End Sub

Sub SendEmail(ByVal Vendor As String, ByVal attachmentFileName As String)
'Send Email
End Sub
 

Комментарии:

1. «Мне нужно запустить отправку почты после ответа. Конец» — почему? Каковы ваши доводы в пользу этого? И почему у вас есть Ниточка. Спать в своем коде? Почему вы предоставляете CSV-файл с типом MIME Excel?

2. Функция SendEmail() отправляет электронное письмо с файлом csv, созданным в виде вложения. Нить. Режим сна приостанавливает код, чтобы убедиться, что файл создан, прежде чем пытаться отправить электронное письмо. Я использую компонент CSVWriter, и в документации указано, что для использования типа MIME Excel

3. Но почему необходимо вызывать SendEmail после Response.End? Почему ты не можешь позвонить туда раньше? Нить. Сон здесь совершенно бесполезен, у вас нет асинхронного кода, поэтому гарантируется, что код, предшествующий ему, будет завершен к тому времени, когда вы туда доберетесь. Нить. Сон только искусственно замедляет ваш код и оказывает негативное влияние на производительность вашего сервера. Уберите его. Что касается документации, в которой говорится об использовании MIME — типа Excel с CSV-какой документацией? Где это написано?

4. Как бы я отправил электронное письмо с вложением, если вложение еще даже не было создано в ExportExcel()?

5. Я не говорил отправлять электронное письмо до создания вложения. Я сказал отправить его до ответа.Конец. Видите ли вы разницу между ними?

Ответ №1:

Корень проблемы здесь в том, что у вас нет четкого способа получить сгенерированный файл в качестве вложения к файлу. Ваш CSVWriter пишет непосредственно в HTTP — ответ. Вместо этого вы можете записать файл в папку на диске или в память. В этот момент вы можете отправить электронное письмо с файлом в качестве вложения. Затем вы можете записать файл в ответ, а затем завершить ответ.

Ваши методы могли бы использовать еще немного разбивки. Я предлагаю один способ создания файла, один способ отправки файла по электронной почте (он у вас уже есть) и другой способ записи файла в ответ.