【问题标题】:Apache Ignite converting UInt16 to Int16Apache Ignite 将 UInt16 转换为 Int16
【发布时间】:2017-12-01 13:22:26
【问题描述】:

我正在使用 Ignite 在某些进程之间传递数据,但遇到了障碍。我有一个类需要保存一个值,该值可能是几种不同的数据类型,我真的不想为其创建单独的对象、缓存和其他资源。因此,为此我将该属性声明为“对象”类型。其中一种可能存储的值类型是 UInt16。但是,当我将对象放回另一侧时,它认为类型是 Int16,这显然会导致一些问题。

我创建了以下显示问题的示例程序。我只是通过即时窗口 testPerson.TestValue.GetType() 测试了该类型。在返回正确 UInt16 的服务器应用程序上,在客户端上它返回 Int16。非常感谢任何帮助!

Person.cs

using System;

namespace Common
{
    [Serializable]
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public object TestValue { get; set; }
    }
}

ClientApp Program.cs

using Apache.Ignite.Core;
using Apache.Ignite.Core.Cache;
using Common;
using System;

namespace ClientApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var config = new IgniteConfiguration
            {
                IgniteInstanceName = "IgniteTest",
                BinaryConfiguration = new Apache.Ignite.Core.Binary.BinaryConfiguration(typeof(Person)),
                ClientMode = true
            };

            IIgnite ignite = Ignition.Start(config);

            ICache<int, Person> peopleCache = ignite.GetOrCreateCache<int, Person>("People");

            Person testPerson = peopleCache.Get(1);

            Console.ReadLine();
        }
    }
}

ServerApp Program.cs

using Apache.Ignite.Core;
using Apache.Ignite.Core.Cache;
using Common;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var config = new IgniteConfiguration
            {
                IgniteInstanceName = "IgniteTest",
                BinaryConfiguration = new Apache.Ignite.Core.Binary.BinaryConfiguration(typeof(Person)),
                ClientMode = false
            };

            IIgnite ignite = Ignition.Start(config);

            UInt16 testValue = 1005;

            var person1 = new Person()
            {
                Id = 1,
                Name = "Bill Cobble",
                TestValue = testValue
            };

            ignite.DestroyCache("People");
            ICache<int, Person> peopleCache = ignite.CreateCache<int, Person>("People");

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            formatter.Serialize(stream, person1);

            stream.Position = 0;
            Person result = formatter.Deserialize(stream) as Person;

            peopleCache.Put(person1.Id, person1);

            Console.ReadLine();
        }
    }
}

【问题讨论】:

    标签: c# ignite


    【解决方案1】:

    Ignite 二进制协议只有int16int32int64,但没有uints(因为它最初是用Java开发的,类型系统很差)。

    所以UInt16 写成Int16 等等。

    Ignite.NET 尽力处理这个问题。如果TestValue 属性是UInt16 类型,它会被正确反序列化。

    但是对于object 类型,Ignite.NET 无法知道原始类型。


    解决方法:

    • 实现IBinarizableIBinarySerializer,写一个额外的字段指示对象类型,手动进行转换
    • 实现ISerializable,在这种情况下,Ignite 将自动保留正确的类型(2.0+ 版)
    • 使用 BinaryFormatter 并将 byte[] 存储在 Ignite 缓存中(如果您不关心 SQL 和 IBinary

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 2019-10-13
      相关资源
      最近更新 更多