Skip to main content
 首页 » 编程设计

c#之Apache Ignite 将 UInt16 转换为 Int16

2024年02月27日28xing901022

我正在使用 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(); 
        } 
    } 
} 

请您参考如下方法:

Ignite二进制协议(protocol)只有int16、int32、int64,没有uints(因为本来就是用 Java 开发,类型系统很差)。

所以UInt16写成Int16等。

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

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


解决方法:

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