内存映射文件(Memory-mapped files)是一种很好的进程间通信方式,它暴露了底层的细节,具有很强的扩展性以及性能。
这里展示一个利用内存映射文件制作的 变量同步工具。
该工具当前存在的问题是:
- 每次会同步变量的所有字段,不能针对某个字段进行同步。
- 没有使用双缓冲,超出64位的字段会出现问题。
- 一个类一个文件,没能充分利用文件的空间。
工具代码
public interface ISerializer<T>
where T :ISerializer<T>
{
void Serialize(BinaryWriter writer);
void Deserialize(BinaryReader reader);
}
public class VariableAllocator
{
public static VariableProxy<T> NewPub<T>()
where T : ISerializer<T>,new()
{
return NewPub<T>("", 4096);
}
public static VariableProxy<T> NewPub<T>(string mapNamePrefix, int capacity)
where T: ISerializer<T>,new()
{
MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateNew(mapNamePrefix+typeof(T).Name, capacity);
var publisher = new VariableProxy<T>(memoryMappedFile);
return publisher;
}
public static VariableProxy<T> NewSub<T>()
where T: ISerializer<T>,new()
{
return NewSub<T>("");
}
public static VariableProxy<T> NewSub<T>(string mapNamePrefix)
where T: ISerializer<T>,new()
{
MemoryMappedFile memoryMappedFile = MemoryMappedFile.OpenExisting(mapNamePrefix + typeof(T).Name);
var publisher = new VariableProxy<T>(memoryMappedFile);
return publisher;
}
}
{
public class VariableProxy<T> : VariableProxy
where T: ISerializer<T>, new()
{
public VariableProxy(MemoryMappedFile memoryMappedFile) : base(memoryMappedFile)
{
}
public void Publish(T val)
{
memoryMappedViewStream.Position = 0;
val.Serialize(writer);
}
public T Subscribe()
{
memoryMappedViewStream.Position = 0;
var val = new T();
val.Deserialize(reader);
return val;
}
}
public class VariableProxy:IDisposable
{
protected MemoryMappedFile memoryMappedFile;
protected MemoryMappedViewStream memoryMappedViewStream;
protected BinaryWriter writer;
protected BinaryReader reader;
public VariableProxy(MemoryMappedFile memoryMappedFile)
{
this.memoryMappedFile = memoryMappedFile;
memoryMappedViewStream = memoryMappedFile.CreateViewStream();
writer = new BinaryWriter(memoryMappedViewStream);
reader = new BinaryReader(memoryMappedViewStream);
}
public void Dispose()
{
memoryMappedFile.Dispose();
memoryMappedViewStream.Dispose();
writer.Dispose();
reader.Dispose();
}
}
变量代码
public class Player:ISerializer<Player>
{
public int Id { get; set; }
public int Age { get; set; }
public int Hp { get; set; }
public void Deserialize(BinaryReader stream)
{
Id = stream.ReadInt32();
Age = stream.ReadInt32();
Hp = stream.ReadInt32();
}
public void Serialize(BinaryWriter stream)
{
stream.Write(Id);
stream.Write(Age);
stream.Write(Hp);
}
}
发送方代码
class Program
{
// Process A:
static void Main(string[] args)
{
Player player = new Player { Id = 1001, Age = 23, Hp = 40000 };
using (var pub = VariableAllocator.NewPub<Player>())
{
while (true)
{
pub.Publish(player);
player.Hp -= 1;
Thread.Sleep(1000);
}
}
}
}
接收方代码
static void Main(string[] args)
{
try
{
using(var sub = VariableAllocator.NewSub<Player>())
{
while (true)
{
Player player = sub.Subscribe();
Console.WriteLine($"ID={player.Id} Age={player.Age} HP={player.Hp}");
}
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
}
}
标签:stream,映射,C#,void,VariableProxy,memoryMappedFile,内存,new,public
From: https://www.cnblogs.com/dewxin/p/17542473.html