Я использую надежную очередь в своем приложении для работы с сервисом Stateful. Когда я пытаюсь поставить в очередь элемент, который, метод Enqueue бросает исключениеОшибка последовательной передачи IReliableQueue Enqueue
код используется
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, его бросает исключение,
Тип 'TestService.CreateCommand' с именем контракта данных 'CreateCommand: http://schemas.datacontract.org/2004/07/TestService' is не ожидается. Подумайте об использовании DataContractResolver, если вы используете DataContractSerializer или добавляете любые типы, не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, переданных в сериализатор .
Трассировка стека
на System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType (DataContract DataContract, XmlWriterDelegator XMLWriter, OBJ Object, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Тип declaredType) в системе .Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel (DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, R untimeTypeHandle originalDeclaredTypeHandle, Тип graphType) при System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent (XmlWriterDelegator писателя, графа объекта, DataContractResolver dataContractResolver) при System.Runtime.Serialization.DataContractSerializer.InternalWriteObject (XmlWriterDelegator писатель, граф объектов, DataContractResolver dataContractResolver) на System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions (XmlWriterDelegator писатель, граф объектов, DataContractResolver dataContractResolver) на System.Runtime.Serialization.XmlObjectSerializer.WriteObject (XmlDictionaryWriter писатель, граф объектов) в Microsoft.ServiceFabric.Replicator.DataContractStateS erializer
1.Write(T value, BinaryWriter binaryWriter) at System.Fabric.Store.TStore
5.GetValueBytes (TValue CurrentValue, TValue новое_значение) при 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() в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задачи) при System.Runtime .CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.GetResult()
на TestService.TestService.d__2.MoveNext() в D: \ Projects \ Local \ ReliableSerialization \ Application1 \ TestService \ TestService.cs: строка 51 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача задача) в Система .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в 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
«DataContractSerializer» сериализует конкретные типы, а не интерфейсы. Взгляните на [Сериализация списка интерфейсов с помощью DataContractSerializer] (https://stackoverflow.com/questions/14937097/serializing-a-list-of-interfaces-using-the-datacontractserializer). – dbc