RickStrahl / Westwind.RazorHosting

Hosting the Razor Runtime outside of ASP.NET/MVC for use in non-Web .NET applications.
144 stars 32 forks source link

Remoting error due to GC issues when using App Domain #28

Open gdodd1977 opened 6 years ago

gdodd1977 commented 6 years ago

I'm getting the following error:

System.Runtime.Remoting.RemotingException: Object ‘/76e7cd41_2cd2_4e89_9c03_fae752ec4d59

/zb_uualy_cm6kwizjlentfdl_3.rem’ has been disconnected or does not exist at the server.

It appears to be due to GC issues when using an App Domain. I see where you have a virtual method on the RazorBaseHostContainer called InitializeLifetimeService(). But the Xml Doc seems to indicate that how you have it should keep it alive indefinitely. We are not finding that to be the case.

Any thoughts on this?

RickStrahl commented 6 years ago

If you use AppDomains any objects you use have to be either [Serializable] or inherit from MarshalByRefObject otherwise you'll get remoting errors as the objects won;t be able to pass over the AppDomain boundaries.

gdodd1977 commented 6 years ago

Everything we are using is Serializable. In the past, when we weren't, we got exceptions thrown.

RickStrahl commented 6 years ago

There's an option ThrowExceptions to turn on the exception behavior. By default this value is false and exception are handled and return an error message instead.

Serializable exceptions can occur even if your top level object is serializable, but one of your subobjects isn't. For example, if you have a DateTimeOffset it may break because that class isn't serializable. Or if you have any other non-serializable child objects.

You can dig into the exception and the stacktrace to hopefully find out exactly which object is failing to serialize either in the parameter list or the return value.

qlayer commented 6 years ago

@RickStrahl This was the stack we've got when we got the exception:

   at Westwind.RazorHosting.RazorEngineConfiguration.get_CompileToMemory()
   at Westwind.RazorHosting.RazorEngine`1.CompileTemplate(TextReader templateReader, String generatedNamespace, String generatedClassName) in Westwind.RazorHosting\Core\RazorEngine.cs:line 550
   at Westwind.RazorHosting.RazorEngine`1.CompileTemplate(String templateText, String generatedNamespace, String generatedClassName) in Westwind.RazorHosting\Core\RazorEngine.cs:line 602  

I think the problem comes from RazorEngineConfiguration : MarshalByRefObject it does not override InitializeLifetimeService method.

RickStrahl commented 5 years ago

Hmmm... maybe RazorEngineConfiguration should just be [Serializable] instead of MarshalByRefObject. There seems to be no good reason for that to be MarshalByRefObject, since it's just a state object. Making the change I don't see any adverse behavior, but it's been so long I don't recall whether there was an explicit reason to use MarshalByRefObject.