当前位置: 首页 > 编程语言 > C#

WCF的DataContractSerilaizer是线程安全的吗?分享

时间:2023-04-11 10:59:07 C#

WCF的DataContractSerilaizer线程安全?我一直在将一个相当大的系统从Remoting转换为WCF,一切似乎都运行良好,只是我们不断收到以下异常:“System.InvalidOperationException:Collection已修改;无法执行枚举操作。“我没有任何运气来追踪它,因为它只发生在有数百个调用通过时,我只能假设这是因为一个对象在序列化后被修改了。所有类都使用:[DataContract(IsReference=true)]。使用远程处理时没有类似的异常,所以我想知道是否有人对WCF有类似的问题或者可以让我知道它可能是序列化程序-在这种情况下我假设我必须编写自己的序列化程序来在必要时执行锁定(这是我宁愿避免的主要任务)。下面是堆栈跟踪:WCF错误:在System.Collections.Generic.List1.Enumerator.MoveNextRare()XmlObjectSerializerWriteContextcontext)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegatorxmlWriter,Objectobj,BooleanisDeclaredType,BooleanwriteXsiType,Int32declaredTypeID,RuntimeTypeHandledeclaredTypeHandle)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegatorxmlWriter,Objectobj,BooleanisDeclaredType,BooleanwriteXsiType,Int32declaredTypeID,RuntimeTypeHandledeclaredTypeHandle)在WriteLineGroupToXml(XmlWriterDelegator,Object,XmlObjectSerializerWriteContext,ClassDataContract)在System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegatorxmlWriter,Objectobj,XmlObjectSerializerWriteContextcontext)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContractdataContract,XmlWriterDelegatorxmlWriter,Objectobj,RuntimeTypeHandledeclaredTypeHandle)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegatorxmlWriter,Objectobj,BooleanisDeclaredType,BooleanwriteXsiType,Int32declaredTypeID,RuntimeTypeHandledeclaredTypeHandle)在System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegatorxmlWriter,Objectobj,BooleanisDeclaredType,BooleanwriteXsiType,Int32declaredTypeID,RuntimeDelegatorWriteHandle)atObjectXmlWriterDelegatorxmlWriter,XmlObjectSerializerWriteContext,ClassDataContract)在System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegatorxmlWriter,Objectobj,XmlObjectSerializerWriteContextcontext)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContractdataContract,XmlWriterDelegatorxmlWriter,Objectobj,BooleanverifyKnownType,RuntimeTypeHandledeclaredTypeHandle,TypedeclaredType)atSystem.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContractdataContract,XmlWriterDelegatorxmlWriter,Objectobj,RuntimeTypeHandleoriginalDeclaredTypeHandle,TypegraphType)在System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegatorwriter,对象图,DataContractResolverdataContractResolver)在System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectwriter(XmlWriter),DataContractResolverdataContractResolver)在System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegatorwriter,对象图,DataContractResolverdataContractResolver)在System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter编写器,对象图)在System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter编写器,PartInfo部分,对象图)在System.ServiceModel。Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter编写器,PartInfo部分,对象图)位于System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter编写器,MessageVersion版本,Object[]参数,ObjectreturnValue,BooleanisRequest)在System.ServiceModel.Dispatcher.OperationForSystem.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter编写器)在System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter编写器)在System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter编写器)在System.ServiceModel.Channels.OnWriteMessage(Message.OnWriteMessage)XmlDictionaryWriter编写器)在System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter编写器)在System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(消息消息,BufferManagerbufferManager,Int32initialOffset,Int32maxSizeQuota)在System.ServiceModel.Channels.BinaryMessageEncoderFactory.BinaryMessageEncoder在System.ServiceModel.Channels.FramingDuplexSessionChannel.EncodeMessage(消息消息)在System.ServiceModel.Channels.FramingDuplexSessionChannel.OnSend(Mess年龄消息,TimeSpan超时)在System.ServiceModel.Channels.OutputChannel.Send(消息消息,TimeSpan超时)在System.ServiceModel.Dispatcher.DuplexChannelBinder.DuplexRequestContext.OnReply(消息消息,TimeSpan超时)在System.ServiceModel.Channels.RequestContextBase.Reply(Messagemessage,TimeSpantimeout)atSystem.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc&rpc)实践上,使用DataContractSerializer可以轻松地重现此错误不是DataContractSerializer的线程安全,是一些集合的线程安全,对于你的数据契约:[DataContract]publicclassC{[DataMember]publicListValues{get;放;}}classProgram{staticvoidMain(string[]args){varc=newC{Values=newList()};varserializer=newDataContractSerializer(typeof(C));Task.Factory.StartNew(()=>{while(true){Console.WriteLine("尝试添加新项目。");c.Values.Add(DateTime.Now.Millisecond);}},TaskCreationOptions.LongRunning);Task.Factory.StartNew(()=>{while(true){using(varstream=newMemoryStream()){Console.WriteLine("Tryingtoserialize.");serializer.WriteObject(stream,c);}}},TaskCreationOptions.LongRunning);控制台.ReadLine();在短暂的执行时间后,您将获得一个带有堆栈跟踪的IOE,例如:.List`1.Enumerator.MoveNext()在WriteArrayOfintToXml(XmlWriterDelegator,Object,XmlObjectSerializerWriteContext,CollectionDataContract)atSystem.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegatorxmlWriter,Objectobj,XmlObjectSerializerWriteContextcontext)看起来你在序列化时继续修改一些共享数据你可以打开WCF跟踪(见这个问题)找出导致错误的操作,并仔细查看此操作使用的数据。然后,根据当前服务行为的InstanceContextMode和ConcurrencyMode属性的值,您可以选择走哪条路:如果丹尼斯的假设是正确的,解决这个问题最简单的方法是复制集合并发送一个通过电线复制。此时,连载时原始内容是否被修改都无所谓了。以上就是C#学习教程:WCF的DataContractSerilaizer是线程安全的吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢