gpt4 book ai didi

c# - IReliableQueue 入队序列化错误

转载 作者:行者123 更新时间:2023-11-30 21:46:19 25 4
gpt4 key购买 nike

我在我的有状态服务结构应用程序中使用可靠队列。当我尝试将一个项目入队时,入队方法抛出异常

使用的代码是

 protected override async Task RunAsync(CancellationToken cancellationToken)
{
ICommand myItem = new CreateCommand()
{
Data = "Sample Data",
Id = Guid.NewGuid(),
TenentName = "SampleTenant"
};
var myQueue = await this.StateManager.GetOrAddAsync<IReliableQueue<ICommand>>("CommandQueue");
using (var tx = StateManager.CreateTransaction())
{
await myQueue.EnqueueAsync(tx, myItem, TimeSpan.FromSeconds(4), cancellationToken);
await tx.CommitAsync();
}
using (var tx = StateManager.CreateTransaction())
{
var dq = await myQueue.TryDequeueAsync(tx);
await tx.CommitAsync();
}
}
}

public interface ICommand
{
Guid Id { get; set; }
string TenentName { get; set; }
}


public class CreateCommand : ICommand
{
public Guid Id { get; set; }
public string TenentName { get; set; }
public string Data { get; set; }
}

在 myQueue.EnqueueAsync 上,它抛出异常

Type 'TestService.CreateCommand' with data contract name 'CreateCommand:http://schemas.datacontract.org/2004/07/TestService' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

堆栈跟踪

at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph) at Microsoft.ServiceFabric.Replicator.DataContractStateSerializer1.Write(T
value, BinaryWriter binaryWriter) at
System.Fabric.Store.TStore
5.GetValueBytes(TValue currentValue, TValue newValue) at System.Fabric.Store.TStore5.<AddAsync>d__4.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
Microsoft.ServiceFabric.Data.Collections.DistributedQueue
1.d__9.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at TestService.TestService.d__2.MoveNext() in D:\Projects\Local\ReliableSerialization\Application1\TestService\TestService.cs:line 51 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ServiceFabric.Services.Runtime.StatefulServiceReplicaAdapter.d__f.MoveNext()

当我更改代码以使用具体类型时,它工作正常。

以我为例 IReliableQueue<CreateCommand>

它运行良好。

我的代码引用:https://github.com/Azure-Samples/service-fabric-dotnet-iot/blob/master/src/gateway/IoTProcessorManagement.Common/WorkManagement/WorkManager.cs

最佳答案

您的类型缺少 DataContract 和 DataMember 属性,并且由于数据协定序列化工作方式的实现,您不能将 DataContract 属性放在接口(interface)上。缺少数据协定属性可能导致难以追踪错误,因为 Service Fabric 将在内部存储对对象的引用并在您出列时返回该引用,但在提交时将对象发送到辅助对象时序列化该对象。当您忘记上述属性时,您会看到它有时似乎可以工作,但要么会抛出提交事务,要么您将拥有看似良好的填充对象,直到服务重新启动(对于升级,如果该节点去下来,或其他一些原因)然后将是空的(缺少属性的字段将为空/默认)。

要在数据协定中利用多态性,您可以使用基类和 KnownType 属性。这就是您的示例在添加删除命令后的样子。

[DataContract]
[KnownType(typeof(CreateCommand))]
[KnownType(typeof(DeleteCommand))]
public class BaseCommand
{
[DataMember]
public Guid Id { get; set; }

[DataMember]
public string TenentName { get; set; }
}

[DataContract]
public class CreateCommand : BaseCommand
{
[DataMember]
public string Data { get; set; }
}

[DataContract]
public class DeleteCommand : BaseCommand
{
[DataMember]
public string SomeOtherData { get; set; }
}

另请注意,已知类型属性支持传入函数以编程方式发现子类型,但请勿使用它,因为它会以奇怪且难以诊断的方式破坏可升级性。

关于c# - IReliableQueue 入队序列化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39343161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com