Nlog: Remoting Issue

Created on 25 Sep 2019  路  4Comments  路  Source: NLog/NLog

NLog version: NLog 4.6.5

Platform: .Net 4.7

Hi,

When using Remoting NLog requires the remoting server to have a reference to NLog or else it will throw an exception.

System.Runtime.Serialization.SerializationException: Unable to find assembly 'NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c'.

Server stack trace: 
   at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
   at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryPar
ser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryRequestMessage(String objectUri, Stream inputStream, Boolean bStrictBinding, TypeFilterLevel securityLevel)
   at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage r
etMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at RemotingInterface.Foo.GetBar()
   at RemotingClient.Controllers.FooController.GetBar() in C:\\Users\\oso\\Desktop\\lixo\\SimpleSample_Src\\RemotingClient\\Controllers\\FooController.cs:line 23
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

This happens because NLog uses System.Runtime.Remoting.Messaging.CallContextinstead of System.Threading.AsyncLocal<INestedContext> for .NET 4.7 applications (there is no target framework > net45 built).

I created a sample application that shows this issue:

  1. Start the server;
  2. Start the Client
  3. Access http://localhost:5000/Foo
question

All 4 comments

Strange that NLog affects what is sent together with remoting. Thought it would only transport objects that what wrapped in something that implemented ILogicalThreadAffinative Interface :

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.remoting.messaging.ilogicalthreadaffinative

Looks like this "rule" only works for objects assigned using System.Runtime.Remoting.Messaging.CallContext.SetData instead of System.Runtime.Remoting.Messaging.CallContext.LogicalSetData

I guess a workaround is to setup your AspNetCore-application to have IncludeScopes=false until a better version of NLog arrives that can use AsyncLocal on net472 (along with portable pdb-symbols-support).

https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-LoggerProvider-Options

Another work-around is to use NLog in the Server-application.

Yet another work-around is to have a dedicated thread that performs system-remoting calls. Instead of calling directly from ASP.NET.Core-threads then push to a queue. And have a dedicated-long-living-thread that monitors this queues and performs the system-remoting-calls. The dedicated thread will then not be "polluted" by the BeginScope-calls performed by the ASP.NET.Core-threads.

When adding a new targetplatform to NLog, then we also need to unit test this platform. And it would be nice if some could be removed as well (Ex Xamarin iOS + Xamarin Android + Silverlight + WindowsPhone + net40). But removing targetplatform would require major-version-jump to NLog5.

I assume your question has been answered, if not, please let us know!

Sorry for the late reply. It was was thanks!

Was this page helpful?
0 / 5 - 0 ratings