Re: Threading with an object and Session



A background thread should not access the HttpContext or the Request. Both
of these are invalid once the page is done processing. Have the background
thread post the mail body directly to the session, or to some other global
scope. A subsequent request can then discover and use it.

David

"Gavin Lyons via .NET 247" <anonymous@xxxxxxxxxxxxx> wrote in message
news:eZh57wSYFHA.3488@xxxxxxxxxxxxxxxxxxxxxxx
Hello,

I'm writing a newsletter application which uses background threading. I'm
using Session variable to report on progress while it loops through a
dataset. The 'Status.aspx' page refreshes every 5 seconds while outputing
the Session variables. My problem is, once the page redirects to
'Status.aspx' its show the that's it only gets half through the dataset. If
I increase Thread.Sleep to 2000 goes all the way through. I don't get any
error message, it's like the MailObj disappears once the page redirects. Do
I need to use something like Context.Items.Add ?

Any ideas would be great:)

Gavin Lyons




private void Send_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
if (Subject.Text!="")
{
string SQLString = "SELECT * FROM Members";
i386.Newsletter.mailer MailObj = new mailer();
MailObj.SMTPhost = "mail.smtp.com";
MailObj.From = From.SelectedValue;
MailObj.Body = Body();
MailObj.Sessions = true;
MailObj.EmailAddressField = "UserID";
MailObj.EmailNameField = "<!--FirstName--> <!--LastName-->";
MailObj.DataSet = i386.DatabaseSystem.GetDataSet(SQLString,
"WebConfigDatabaseConnection");
MailObj.WebContext = (System.Web.HttpContext)Session["WebContext"];

Thread thread = new Thread(new ThreadStart(MailObj.Send));
thread.Priority = ThreadPriority.Lowest;
thread.Start();
Thread.Sleep(500);
Response.Redirect("status.aspx", true);

}
else
Label_Message.Text="Missing data!";


}



public class mailer
{
private string _SMTPhost="localhost";
private string _Body="";
private string _From="";
private string _FromName="";
private string _Subject="";
private string _DatabaseConnection;
private string _EmailAddressField;
private string _EmailNameField;
private System.Web.HttpContext _WebContext;
private DataSet _DataSet;
private bool _Sessions=true;
public string SMTPhost
{
get {return _SMTPhost;}
set {_SMTPhost=value;}
}
public string EmailNameField
{
get {return _EmailNameField;}
set {_EmailNameField=value;}
}
public string EmailAddressField
{
get {return _EmailAddressField;}
set {_EmailAddressField=value;}
}
public string Body
{
get {return _Body;}
set {_Body=value;}
}
public string Subject
{
get {return _Subject;}
set {_Subject=value;}
}
public string From
{
get {return _From;}
set {_From=value;}
}
public string FromName
{
get {return _FromName;}
set {_FromName=value;}
}
public bool Sessions
{
get {return _Sessions;}
set {_Sessions=value;}
}
public DataSet DataSet
{
set {_DataSet=value;}
get {return _DataSet;}
}
public System.Web.HttpContext WebContext
{
set {_WebContext=value;}
get {return _WebContext;}
}
private string ReplaceFields(DataRow DR, string String)
{
string ReplStr = String;
foreach (DataColumn Column in DR.Table.Columns)
{
ReplStr = ReplStr.Replace("<!--" + Column.ToString() + "-->",
DR[Column.ToString()].ToString());
}
return ReplStr;
}
public void Send()
{
try
{
#region Initialise Sessions
if (this.Sessions)
{
lock(WebContext.Session.SyncRoot )//lock the session object
{
StringBuilder sb = new StringBuilder(); // for reporting

WebContext.Session["StatusLine"] = "Retrieving data to send ..";
WebContext.Session["EmailReport"] = sb;
WebContext.Session["EmailCounter"] = "0";
WebContext.Session["TotalEmailsToSend"] =0;
WebContext.Session["Done"] = "false";
WebContext.Session["TotalEmailsToSend"] =
this.DataSet.Tables[0].Rows.Count.ToString();
}
}
else
{
WebContext.Response.Write("Retrieving data to send ..");
}
#endregion
// Newsletter Merging
int startAt = Environment.TickCount;
int EmailCounter = 0;
bool TestMode = true;
foreach (DataRow DR in this.DataSet.Tables[0].Rows)
{
#region loop sending

// SMTP stmpobj = new SMTP(this.SMTPhost);
// EmailMessage emailmsg = new EmailMessage();

string BodyForEmail = ReplaceFields(DR, this.Body);
string ToForEmail = DR[this.EmailAddressField].ToString();
string ToNameForEmail = ReplaceFields(DR, this.EmailNameField);
string SubjectForEmail = ReplaceFields(DR, this.Subject);


if (this.Sessions)
{
lock(WebContext.Session.SyncRoot )
{
WebContext.Session[ "StatusLine" ] = "Processing " + ToForEmail;
}
}
try
{
if (!TestMode)
{
//stmpobj.Send(emailmsg)
}
else
{

WebContext.Response.Write("Sending to "+ ToForEmail + "(" + ToNameForEmail +
") " + WebContext.Session[ "StatusLine" ].ToString() + "<br/>");
}
if (this.Sessions)
{ // Reporting
((StringBuilder)WebContext.Session["EmailReport"]).Append(EmailCounter+ ","
+ DR["UserID"].ToString() +
", " + DateTime.Now.ToString() + ", Successful<BR>" );// Reporting
}
}
catch (Exception ErrorMsg)
{
if (this.Sessions)
{ // Reporting
((StringBuilder)WebContext.Session["EmailReport"]).Append(EmailCounter+ ","
+ DR["UserID"].ToString() +
", " + DateTime.Now.ToString() + ", Failed:" + ErrorMsg.Message + "<BR>" );
}
}
EmailCounter++;
if (this.Sessions)
{
lock(WebContext.Session.SyncRoot)
WebContext.Session[ "EmailCounter" ] = EmailCounter;
}
#endregion
}
#region Sessions Final Values
if (this.Sessions)
{
lock( WebContext.Session.SyncRoot )
{
int ms = Environment.TickCount - startAt;
int seconds = ms/1000;
WebContext.Session[ "SecondsForMailMerge" ] = seconds.ToString();
WebContext.Session["Done"] = true;
WebContext.Session["StatusLine"] = "Newsletter Completed!";
}
}
#endregion
// this.DataSet.Dispose();
}
catch (Exception ex)
{
#region Session Report with Error
if (this.Sessions)
{
lock(WebContext.Session.SyncRoot )
{
WebContext.Session["MailMergeException"] = ex;
}
}
#endregion
WebContext.Response.Write("Mailer Error:" + ex.Message);
}
}
}
--------------------------------
From: Gavin Lyons

-----------------------
Posted by a user from .NET 247 (http://www.dotnet247.com/)

<Id>f7YLYLMHKUi+IHe+JkwBWg==</Id>


.



Relevant Pages

  • Re: BinaryFormatter.Deserialize
    ... > private Guid session; // 16 bytes ... > private string DNIS; ... > private string applicationQueue; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: BinaryFormatter.Deserialize
    ... private Guid session; // 16 bytes ... private string DNIS; ... applicationQueue = info.GetValue); ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Setting id in a dynmaically generated checkboxlist
    ... > protected Repeater Repeater1; ... > public Category(string title, string explanation, ... > public string Explanation ... > private string explanation; ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: BinaryFormatter.Deserialize
    ... private string DNIS; ... public ApplicationInfo(string session, string sessionNW, string ANI, string ... DNIS, string mqNW, string parent, string child, string applicationQueue, int ...
    (microsoft.public.dotnet.languages.csharp)
  • Default.aspx.cs
    ... string strReturn = SendInvitations(txtName.Text, ... private string SendInvitations(string name, string body, string ... emails, string codedString, ArrayList friend) ... public string subject ...
    (microsoft.public.dotnet.languages.csharp)