problem in data logging from within HttpListener

K

Kunal

Hi friends,

I have tried to host a web service using HttpListener of .NET 2.0 (with
help from the article
http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx).

The server runs fine, accepts and responds to requests just fine. I'm
using the synchronous model (GetContext). One of my requirements is to
log the incoming data to a text file. For this I create a separate
thread in the same namespace to send the data to via a message queue.
This thread logs the data to file while it is being processed
simultaneously. Data is written to the file correctly, the correct
response is generated and sent to the client. Around 2 secs after this
the server crashes with the exception -

System.AppDomainUnloadedException: The application domain in which the
thread was running has been unloaded.

Server stack trace:
at System.Threading.Thread.InternalCrossContextCallback(Context ctx,
IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate
ftnToCall, Object[] args)
at
System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatch(Byte[]
reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
SmuggledMethodReturnMessage& smuggledMrm)
at
System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage
reqMsg)

Exception rethrown at [0]:
at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg)
at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
at HttpListenerLibrary.HttpListenerWrapper.ProcessRequest()
at HttpListenerLibrary.HttpListenerController.Pump() in C:\StarTeam
Original
code\easycare\Software\Release\SimulatorsDev\AcsSim\HttpListenerLibrary\HttpListenerLibrary.cs:line
166Error

I tried the following options -


1) I created the receiver thread in another namespace.

2) First I was sending data from ReadEntityBody overrided function. I
changed this to SendResponseFromMemory.

3) I changed different ways of writing to file.

But no success. Can anybody please help me and let me know what the
problem could be and how I can achieve what I want to ?
The server is compiled as a dll in my project.

Thanks,

Kunal
 
V

Vadym Stetsyak

Hello, Kunal!

One of the reasons maybe that object's lifetime expires
(
http://vadmyst.blogspot.com/2006/03/issues-when-using-marshalbyrefobject.html )

I assume that to transfer messages to the logger you're using class that
inherits from MarshalByRefObject?

You wrote on 18 Dec 2006 14:27:11 -0800:

K> I have tried to host a web service using HttpListener of .NET 2.0 (with
K> help from the article
K> http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.as
K> px).

K> The server runs fine, accepts and responds to requests just fine. I'm
K> using the synchronous model (GetContext). One of my requirements is to
K> log the incoming data to a text file. For this I create a separate
K> thread in the same namespace to send the data to via a message queue.
K> This thread logs the data to file while it is being processed
K> simultaneously. Data is written to the file correctly, the correct
K> response is generated and sent to the client. Around 2 secs after this
K> the server crashes with the exception -

K> System.AppDomainUnloadedException: The application domain in which the
K> thread was running has been unloaded.

K> Server stack trace:
K> at System.Threading.Thread.InternalCrossContextCallback(Context ctx,
K> IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate
K> ftnToCall, Object[] args)
K> at
K> System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatch
K> (Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
K> SmuggledMethodReturnMessage& smuggledMrm)
K> at
K> System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(I
K> Message reqMsg)

K> Exception rethrown at [0]:
K> at
K> System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
K> reqMsg, IMessage retMsg)
K> at
K> System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
K> msgData, Int32 type)
K> at HttpListenerLibrary.HttpListenerWrapper.ProcessRequest()
K> at HttpListenerLibrary.HttpListenerController.Pump() in C:\StarTeam
K> Original
K> code\easycare\Software\Release\SimulatorsDev\AcsSim\HttpListenerLibrary\
K> HttpListenerLibrary.cs:line 166Error

K> I tried the following options -

K> 1) I created the receiver thread in another namespace.

K> 2) First I was sending data from ReadEntityBody overrided function. I
K> changed this to SendResponseFromMemory.

K> 3) I changed different ways of writing to file.

K> But no success. Can anybody please help me and let me know what the
K> problem could be and how I can achieve what I want to ?
K> The server is compiled as a dll in my project.

K> Thanks,


With best regards, Vadym Stetsyak. E-mail: (e-mail address removed)
 
K

Kunal

Hi Vadym,

Thanks for responding and apologies for not being too clear.

I have two main namespaces. First handles a form, which is basically
the UI of my server. Second one implements the HttpListener. None of
the classes here inherit from MarshalByRefObject.

Within first, I create a private queue on my host (MSMQ) and start a
thread. This thread waits endlessly over the queue for a new message.
If it receives a message, it writes it to a file and goes back to check
new messages.

In HttpListener, I receive the web request (using GetContext). Then I
read the input stream, get it into a string, send that string over to
the private queue I created and go further with processing. The reading
and sending of data is done in ReadEntityBody overrided function.

The request is received, message body is read, sent to queue, read by
logger thread and written to the file. The request is processed and
appropriate response is generated, sent and request ends. This is where
I get the AppDomain error comes.

I'm not explicitly creating any Application Domains here. Since I'm a
newbie to .NET I do not well understand the concept too :((

I hope this gives you enough info to be able for you to suggest
something.

Thanks,
Kunal
 
V

Vadym Stetsyak

Hello, Kunal!

If you're hosting ASP.NET or use it to simulate web services, you're dealing
with separate app domains.
Web services code executes in its own app domain.

Remoting architecture makes the process of data marshalling between
AppDomain transparent.

To check if marshalling takes place in your situation try
to debug and check what types have objects that you use for message
processing.
If there will be TransparentProxy type that means that marshalling is
present.

You wrote on 19 Dec 2006 08:54:21 -0800:

K> Hi Vadym,

K> Thanks for responding and apologies for not being too clear.

K> I have two main namespaces. First handles a form, which is basically
K> the UI of my server. Second one implements the HttpListener. None of
K> the classes here inherit from MarshalByRefObject.

K> Within first, I create a private queue on my host (MSMQ) and start a
K> thread. This thread waits endlessly over the queue for a new message.
K> If it receives a message, it writes it to a file and goes back to
K> check
K> new messages.

K> In HttpListener, I receive the web request (using GetContext). Then I
K> read the input stream, get it into a string, send that string over to
K> the private queue I created and go further with processing. The
K> reading
K> and sending of data is done in ReadEntityBody overrided function.

K> The request is received, message body is read, sent to queue, read by
K> logger thread and written to the file. The request is processed and
K> appropriate response is generated, sent and request ends. This is
K> where
K> I get the AppDomain error comes.

K> I'm not explicitly creating any Application Domains here. Since I'm a
K> newbie to .NET I do not well understand the concept too :((

K> I hope this gives you enough info to be able for you to suggest
K> something.

K> Thanks,
K> Kunal




With best regards, Vadym Stetsyak.
Blog: http://vadmyst.blogspot.com
 

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