Thread fails to start when called from Server.Execute

B

Brent

Page1.aspx calls Page2.aspx like this:

----------------
Server.Execute("Page2.aspx");
---------------

Page2.aspx's Page_Load event calls a function, getMsgs().This function
runs normally when it is called directly, as in

---------------
getMsgs()
---------------

However, when called on a thread, it doesn't appear to start. I'm
really at a loss to know where to check or monitor the thread for
errors. The threading code looks like this:

--------------
try
{
Thread trd = new Thread(new
ThreadStart(this.getMsgs));
trd.IsBackground = true;
trd.Start();
Thread.Sleep(1000);
}
catch (Exception ex)
{
logEvent.write("Could not start getMsgs. Error: " +
ex.Message);//custom event logger

}

---------------

I'd very much appreciate any tips you may have.

Thanks.

--Brent
 
J

Jon Skeet [C# MVP]

Brent said:
Page1.aspx calls Page2.aspx like this:

----------------
Server.Execute("Page2.aspx");
---------------

Page2.aspx's Page_Load event calls a function, getMsgs().This function
runs normally when it is called directly, as in

---------------
getMsgs()
---------------

However, when called on a thread, it doesn't appear to start. I'm
really at a loss to know where to check or monitor the thread for
errors. The threading code looks like this:

I very much doubt that the thread is really failing to start. When you
say "it doesn't appear to start" how are you determining that?

Have you put logging in at the start of the getMsgs() method?
 
B

Brent

I very much doubt that the thread is really failing to start. When you
say "it doesn't appear to start" how are you determining that?

Have you put logging in at the start of the getMsgs() method?

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

Yes. That's the odd thing. I have done something like this:

try
{
logEvent.write("Before thread start");
Thread trd = new Thread(new
ThreadStart(this.getMsgs));
trd.IsBackground = true;
trd.Start();
logEvent.write("After thread start");
Thread.Sleep(1000);
}
catch (Exception ex)
{
logEvent.write("Could not start getMsgs. Error: " +
ex.Message);//custom event logger

}

....and then, in getMsgs()
-----------------------

void getMsgs()
{
logEvent.write("getMsgs started.");
}

---------------------

....only to find that the getMsgs event log entry ("getMsgs started")
never got written. The two event log entries in the Page_Load event
did appear, however.

I read somewhere that a StackTrace could sometimes prevent a thread
from running properly, so I removed all that from my error reporting,
in hopes a little voodoo might help. Nothing.

I'm a bit at a loss, really.

Thanks for your reply!

--Brent
 
J

Jon Skeet [C# MVP]

...only to find that the getMsgs event log entry ("getMsgs started")
never got written. The two event log entries in the Page_Load event
did appear, however.

How is logEvent declared? Is it thread-static or anything like that? If
you use a debugger and put a breakpoint in getMsgs(), does that ever
get hit?
I read somewhere that a StackTrace could sometimes prevent a thread
from running properly, so I removed all that from my error reporting,
in hopes a little voodoo might help. Nothing.

I'd want to see some more detail about that - it sounds pretty
unlikely.
 
B

Brent

How is logEvent declared? Is it thread-static or anything like that? If
you use a debugger and put a breakpoint in getMsgs(), does that ever
get hit?


I'd want to see some more detail about that - it sounds pretty
unlikely.

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

logEvent is a static method declared in a DLL referenced on the page.
I also tried logging with another custom logging method that isn't
static, but there was no difference, e.g. the log.error line here
wrote nothing:

void getMsgs()
{
Log log = new Log();

log.error("Thread started");

}

I'm confused, I must say.
 
B

Brent

I really appreciate your help.

For some further information, I've simplified the page to this, and it
still doesn't work:
--------------------------------------------------------

<%@ Page Language="C#" EnableViewState="false"%>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text.RegularExpressions" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Threading" %>
<%@ Import Namespace="toolbox" %>

<script language="C#" runat="server">

public void Page_Load(Object sender, EventArgs e)
{
Log log = new Log();

log.error("before thread"); <--write OK

Thread trd = new Thread(new ThreadStart(this.getMsgs));
trd.IsBackground = true;
trd.Start();
Thread.Sleep(1000);

log.error("after thread"); //<---write OK

}

public void getMsgs()
{
Log log = new Log();
log.error("getMsgs started");// <---never does anything
}

</script>
---------------------------------------------

The Log class, declared in toolbox.dll, looks like this:

-------------------------------------------

public class Log
{

static readonly object lockErrorLog = new object();
public void error(string sError)
{
string sPath = HttpContext.Current.Server.MapPath("/") +
"logfiles";
if (!Directory.Exists(sPath))
{
Directory.CreateDirectory(sPath);
}

string sLogName = DateTime.Now.ToString("yyyy-MM-dd");

sPath = sPath + "\\Errors_" + sLogName + ".txt";

lock (lockErrorLog)
{
try
{
if (!File.Exists(sPath))
{
using (StreamWriter sw =
File.CreateText(sPath))
{
sw.WriteLine(sError);

sw.WriteLine("==============================================");
sw.WriteLine("");
}
}
else
{
using (StreamWriter sw =
File.AppendText(sPath))
{
sw.WriteLine(sError);

sw.WriteLine("==============================================");
sw.WriteLine("");
}
}
}
catch { }
}
}
}
 
J

Jon Skeet [C# MVP]

I really appreciate your help.

For some further information, I've simplified the page to this, and it
still doesn't work:

<snip>

It's the logging that's the problem. Where it's using
HttpContext.Current, that's a per-thread context - the new thread
doesn't *have* an HttpContext.

Try logging by writing to a hard-coded path in a way which doesn't use
*anything* from ASP.NET - make sure you have access to the path from
within the ASP.NET account though. I'm pretty sure you'll find it logs
okay then.

Jon
 
B

Brent

<snip>

It's the logging that's the problem. Where it's using
HttpContext.Current, that's a per-thread context - the new thread
doesn't *have* an HttpContext.

Try logging by writing to a hard-coded path in a way which doesn't use
*anything* from ASP.NET - make sure you have access to the path from
within the ASP.NET account though. I'm pretty sure you'll find it logs
okay then.

Jon

Jon:

This did it. I added a new entry to Web.config, and that effectively
hard-coded the path.

This bug I don't know I would have ever caught. It wouldn't have shown
up in any try-catch block inside a thread, and have been invisible to
me. Thanks to your insight, I'm back on track.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top