public struct Candle //88 bytes struct
{
[DataMember(Order = 1)] public long TimeStamp { get; }
[DataMember(Order = 2)] public decimal Open { get; }
[DataMember(Order = 3)] public decimal High { get; }
[DataMember(Order = 4)] public decimal Low { get; }
[DataMember(Order = 5)] public decimal Close { get; }
[DataMember(Order = 6)] public decimal Volume { get; }
}
I have such a model, I can pass it in the form Task<IEnumerable<Candle>>
But I can’t pass it as IAsyncEnumerable<Candle>
but as soon as I change struct to class everything starts working, but I can't use it because of allocations
> System.TypeInitializationException : The type initializer for
> 'DefaultProxyCache`1' threw an exception. ---->
> System.InvalidOperationException : Error obtaining client-helper
> 'ServerStreamingAsync' (from: 'IODataModule.Shared.GetRangeArgument',
> to: 'Domain.Candle'): GenericArguments[1], 'Domain.Candle', on
> 'System.Collections.Generic.IAsyncEnumerable`1[TResponse]
> ServerStreamingAsync[TRequest,TResponse](ProtoBuf.Grpc.CallContext
> ByRef, Grpc.Core.CallInvoker, Grpc.Core.Method`2[TRequest,TResponse],
> TRequest, System.String)' violates the constraint of type 'TResponse'.
I am try, to create wrapper like
[DataContract]
public class CandleDto
{
[DataMember(Order = 1)]
public ReadOnlyMemory<Candle> CandleBatch { get; set; }
}
and send it by IAsyncEnumerable
but it throw
> System.TypeInitializationException : The type initializer for
> 'DefaultProxyCache`1' threw an exception. ---->
> System.Reflection.TargetInvocationException : Exception has been
> thrown by the target of an invocation. ---->
> System.InvalidOperationException : No marshaller available for
> IODataModule.Shared.CandleDto
but it work for
[DataContract]
public class CandleDto
{
[DataMember(Order = 1)]
public ReadOnlyMemory<byte> CandleBatch { get; set; }
}
this is my contract
[ServiceContract]
public interface ICandleAccessServiceGrpc
{
[OperationContract]
IAsyncEnumerable<CandleDto> GetRangeStream(GetRangeArgument argument, CallContext context = default);
}
This comes from an annoying
: classconstraint in the base gRPC bits; I have tried multiple times to have this constraint relaxed (I even did the impact analysis and code changes at least once), but; no joy yet. Protobuf-net could in theory add a fake box layer to work around it, but: to date I simply haven't had time to implement everything I would like to. Questions like this are very helpful for helping me prioritize.For the second one: I'm not quite sure what you're trying to do with the ROM-byte - if this is intended as "punning", then maybe that's something we could do more efficiently for you inside the library, but: punning isn't exactly 100% pure protobuf, ans won't have the same correctness guarantees (especially endianness between CPU architectures). However, IIRC it should work - check whether you're using the correct V3 version of protobuf-net (it won't work in V2).