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