【发布时间】:2010-08-23 14:24:25
【问题描述】:
我的应用程序出现远程处理问题。由于架构相当复杂,我将尝试用虚拟名称做一个简单的示例来说明问题。
考虑这些组件:
- MyApp.Client.exe:客户端应用程序
- MyApp.Service.exe:托管服务器的 Windows 服务
- MyApp.Server.dll:服务器实现
- MyApp.Shared.dll:包含通用接口和类型定义的共享库
在 MyApp.Shared.dll 中,我有这些接口:
public interface IFoo
{
...
}
public interface IFooManager
{
IList<IFoo> GetFooList();
...
}
这两个接口都在 MyApp.Server.dll 中实现为MarshalByRefObjects:
class Foo : MarshalByRefObject, IFoo
{
...
}
class FooManager : MarshalByRefObject, IFooManager
{
public IList<IFoo> GetFooList()
{
IList<IFoo> foos = new List<IFoo>();
// populate the list with instances of Foo
// ...
return foos;
}
...
}
在客户端,我有一个代理实例指向服务器上的 FooManager 对象。当我在其上调用GetFooList 时,我可以看到FooManager.GetFooList() 方法已执行,但是当它返回时,我得到以下SerializationException:
Unable to find assembly 'MyApp.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
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.ObjectMap.Create(String name, 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.__BinaryParser.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.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
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 MyApp.Shared.IFooManager.GetFooList()
...
at MyApp.Client.ViewModel.MainWindowViewModel.LoadFoos()
...
所以我猜它正在尝试序列化Foo 类(当GetFooList 返回一个空列表时我没有得到异常)或Foo 中使用的其他类型。但是为什么它会尝试序列化它呢?由于Foo 是MarshalByRefObject,它不应该将代理返回到Foo 实例吗?无论如何,IFoo 接口不会暴露 MyApp.Server.dll 中定义的任何类型的对象...
问题之前没有出现,因为所有程序集都在同一个目录中,因此 MyApp.Server.dll 可能已加载到客户端 AppDomain 中(这不应该发生)。但是现在我正在尝试将客户端和服务器组件分开,因此客户端不应该依赖于服务器端程序集...
有人知道发生了什么吗?我怎样才能获得有关异常的更多详细信息(例如,它试图序列化哪种类型)?堆栈跟踪不是很有帮助...
【问题讨论】:
标签: c# .net serialization remoting