Потоки не запускаются в ASP.Net на сервере, но работают нормально локально - PullRequest
1 голос
/ 15 марта 2012

Я работал над своим первым использованием потоков в приложении ASP.Net и столкнулся с проблемой.

Код работает нормально, когда я запускаю его локально, но как только я загрузил его на наш dev-сервер, он не запускается, но также не выдает ошибку.

Я провел некоторое исследование и обнаружил, что мне нужно, чтобы поток олицетворял WindowsIdentity, что я и сделал, но поток все еще не работает, я также попытался увеличить максимальное количество потоков в IIS и все еще ничего.

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

Я использую IIS 7.5 в Windows 2008 R2.

Метод, выполняемый в новом потоке, находится в классе в папке App_Code и выглядит следующим образом:

Public Class RosterEmailer
      Inherits System.Web.UI.Page

      Dim thisID As String
      Dim thisName As String
      Dim strDutyStartDate As date
      Dim thisWorkEmail As String
      Dim thisHomeEmail As String
      Dim mailbody As string
   Dim Sec As Object 

   Public sub Ini(ByVal _thisID As String, 
                       ByVal _thisName As String, 
                       ByVal _strDutyStartDate As date,
                       ByVal _thisWorkEmail As String,
                       ByVal _thisHomeEmail As String,
                       ByVal _mailbody As string,
                       ByVal _security As Object)

      thisID = _thisID 
      thisName = _thisName 
      strDutyStartDate = _strDutyStartDate 
      thisWorkEmail = _thisWorkEmail 
      thisHomeEmail = _thisHomeEmail 
      mailbody = _mailbody 
      Sec = _security 

   End Sub

   Public Sub SendMail()

    Dim id as  System.Security.Principal.WindowsIdentity  = CType(Sec,System.Security.Principal.WindowsIdentity)
      id.Impersonate()
               'Dim response As System.Web.HttpResponse = System.Web.HttpContext.Current.Response

               'Declare the SMTP server we are going to use 
               Dim smtp As New SmtpClient("192.168.20.11")
               Dim cred As NetworkCredential = New NetworkCredential("domain\\username","mypassword")
               smtp.DeliveryMethod = SmtpDeliveryMethod.Network
               smtp.Credentials = cred

               Dim mail As New MailMessage()

               ' create email
               mail.From = New MailAddress("rostering@ourdomain.com")
               mail.To.Add(thisWorkEmail)
               mail.CC.Add(thisHomeEmail)

               mail.Subject = thisName + " Roster from our company for " + strDutyStartDate.Month.ToString() + "_" + strDutyStartDate.Year.ToString()

               mail.IsBodyHtml = True

               mail.Priority = MailPriority.High

               mail.Body = mailbody

               Dim strURL As String = "http://blueprintdev/Opsproject/Ops/rosteroutput.aspx?InstructorID=" & thisID.ToString() & "&Instructor=" & thisName.ToString() & "&Start=" & strDutyStartDate

               Dim holder As String = String.Empty 

               Dim uu As New Uri(strURL,UriKind.Absolute)
               Dim rq As HttpWebRequest = WebRequest.Create(uu)
               Dim res As HttpWebResponse = rq.GetResponse() 
               Dim stream1 As Stream = res.GetResponseStream()

               Using r1 As StreamReader = New StreamReader(stream1,Encoding.UTF8)
                  holder = r1.ReadToEnd()
               End Using

               Dim pdfConverter As PdfConverter = New PdfConverter
               pdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
               pdfConverter.PdfDocumentOptions.PdfPageOrientation = PDFPageOrientation.Landscape
               pdfConverter.PdfDocumentOptions.PdfCompressionLevel = PdfCompressionLevel.Normal
               pdfConverter.PdfDocumentOptions.ShowHeader = True
               pdfConverter.PdfDocumentOptions.ShowFooter = True
               pdfConverter.PdfDocumentOptions.LeftMargin = 5
               pdfConverter.PdfDocumentOptions.RightMargin = 5
               pdfConverter.PdfDocumentOptions.TopMargin = 5
               pdfConverter.PdfDocumentOptions.BottomMargin = 5
               pdfConverter.PdfDocumentOptions.GenerateSelectablePdf = True

               pdfConverter.PdfDocumentOptions.ShowHeader = False
               pdfConverter.PdfFooterOptions.FooterText = ("Printed on " & Now())
               pdfConverter.PdfFooterOptions.FooterTextColor = Color.DarkBlue
               pdfConverter.PdfFooterOptions.FooterTextFontSize = "10"

               pdfConverter.PdfFooterOptions.FooterTextFontType = PdfFontType.Helvetica
               pdfConverter.PdfFooterOptions.DrawFooterLine = True
               pdfConverter.PdfFooterOptions.PageNumberText = "Page"
               pdfConverter.PdfFooterOptions.PageNumberTextFontType = PdfFontType.Helvetica
               pdfConverter.PdfFooterOptions.PageNumberTextFontSize = "10"
               pdfConverter.PdfFooterOptions.ShowPageNumber = True
               pdfConverter.LicenseKey = "theKeyGoesHere"

               Dim downloadBytes() As Byte = pdfConverter.GetPdfBytesFromHtmlString("<font face='verdana' size='1'>" & holder)

               Dim stream As Stream = New MemoryStream(downloadBytes)

               Dim filename As String = thisName + "_Roster_" + strDutyStartDate.Month.ToString() + "_" + strDutyStartDate.Year.ToString() + ".pdf"

               ' add pdf to email
               Dim att As Attachment = New Attachment(stream, filename, MediaTypeNames.Application.Pdf.ToString())

               mail.Attachments.Add(att)
               ' send email
               smtp.Send(mail)
   End Sub
End Class

Затем я вызываю это из метода в моем коде, например:

Dim sec As System.Security.Principal.WindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent()

       Dim emailer As RosterEmailer = New RosterEmailer()
       emailer.Ini(thisID,thisName,strDutyStartDate,thisWorkEmail,thisHomeEmail,body,sec) 

       Dim Thr As System.Threading.Thread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf emailer.SendMail))

       Thr.Start()

Ответы [ 2 ]

1 голос
/ 04 апреля 2012

Я в целом согласен с рекомендациями здесь. Более конкретно, я бы настроил очередь этих электронных писем (и составляющих их компонентов), которые необходимо отправлять на стороне веб-приложения. Это позволяет выполнять быструю запись в БД и выполнять все действия.

Второй этап заключается в использовании механизма для проверки очереди (таблица в вышеупомянутой БД) и обработки исходящих электронных писем. Простые опции включают приложение без консольного стиля, которое выполняет это при выполнении по расписанию задач в Windows, службу Windows, которая активируется каждые несколько минут для проверки очереди и т. Д. И т. Д.

Поскольку служба Windows выглядит немного тяжело из-за того, что вы делаете, и из-за скорости создания прототипа для консольного приложения, я бы порекомендовал вам перейти в консольное приложение. Это также позволяет очень легко тестировать время выполнения и производительность в средах разработки, тестирования и производства с меньшими издержками при планировании миграции среды.

0 голосов
/ 15 марта 2012

Проблема с WindowsIndentity, которую вы передаете в функцию потока. В ASP.NET в веб-приложении контекст безопасности освобождается после завершения потока запроса. На практике это означает, что WindowsIdentity, передаваемый в фоновом / долгосрочном потоке, перестает работать (например, доступ к свойству Name может привести к ошибке).

Если поток отправителя электронной почты требует, чтобы он выполнялся в области безопасности запрашивающего пользователя (для целей делегирования и т. Д.), Вы должны обернуть свой код в службу, опубликованную с WCF. Хост WCF IIS имеет контекст безопасности для разветвленных потоков. (По моему опыту, это также относится и к серверу Visual Studio Web Dev)

С другой стороны, если вы просто используете свойства WindowsIndentity, а не просто собираете их в потоке запросов и вместо этого передаете эту коллекцию в фоновый поток.

...