using System; using System.Collections.Generic; using System.ComponentModel; using System.IO.MemoryMappedFiles; using System.Linq; using System.Text; namespace Common.MMF { public class MMFHelper { /// <summary> /// 作为服务端实例化(instantize as a server) /// </summary> /// <param name="serverName">服务端名称(server name)<para>需要与客户端的服务端名称保持一致(need to be consistent with the client's server name)</para></param> public MMFHelper(string serverName) { Role = MMFRole.Server; ServerName = serverName; ClientName = ""; InitWorker(); } /// <summary> /// 作为客户端实例化(instantize as a client) /// </summary> /// <param name="serverName">服务端名称(server name)<para>需要与服务端的服务端名称保持一致(need to be consistent with the server name on the service side)</para></param> /// <param name="clientName">客户端名称(client name)</param> public MMFHelper(string serverName, string clientName) { Role = MMFRole.Client; ServerName = serverName; ClientName = clientName; InitWorker(); } ~SimpleMMF() { worker.CancelAsync(); MMFDispose(); } private string ServerName; private string ClientName; private bool IsBusy; private MMFRole Role; private enum MMFRole { Server,Client} private enum MMFType { STATE,VALUE,CLIENT} private BackgroundWorker worker; private static readonly object locker = new object(); /// <summary> /// 作为服务端启动时响应此事件(respond to this event when started as a server)<para>参数e为客户端写入的信息(argument e is the information written by the client)</para><para>key:客户端名称(key: client name)</para><para>value:客户端写入信息(key: the information written by the client)</para> /// </summary> public event EventHandler<KeyValuePair<string, string>> ServerMsg; /// <summary> /// 作为客户端启动时响应此事件(respond to this event when started as a client)<para>参数e为服务端写入的信息(argument e is the information written by the server)</para><para>key:客户端名称(key: client name)</para><para>value:服务端写入信息(key: the information written by the server)</para> /// </summary> public event EventHandler<KeyValuePair<string, string>> ClientMsg; private void InitWorker() { worker = new BackgroundWorker(); worker.WorkerSupportsCancellation = true; worker.DoWork += Worker_DoWork; worker.RunWorkerAsync(); } private void Worker_DoWork(object sender, DoWorkEventArgs e) { while (!e.Cancel) { if (worker.CancellationPending) { e.Cancel = true; continue; } if (IsBusy) continue; string state = MMFRead(MMFType.STATE); if (string.IsNullOrEmpty(state)) continue; if (state == "1") { //内容发生一次改变则只会触发一次事件,之后状态就复原,不能一直去触发。 MMFWrite(MMFType.STATE, "0"); if (Role == MMFRole.Client) { string msg = MMFRead(MMFType.VALUE); string client = MMFRead(MMFType.CLIENT); ClientMsg?.Invoke(this, new KeyValuePair<string, string>(client, msg)); } continue; } if (state == "2") { //内容发生一次改变则只会触发一次事件,之后状态就复原,不能一直去触发。 MMFWrite(MMFType.STATE, "0"); if (Role == MMFRole.Server) { string msg = MMFRead(MMFType.VALUE); string client = MMFRead(MMFType.CLIENT); ServerMsg?.Invoke(this, new KeyValuePair<string, string>(client, msg)); } continue; } } } /// <summary> /// 向共享内存中写入信息(write information to shared memory) /// </summary> /// <param name="msg">待写入信息(the information to be written)</param> public void MMFWrite(string msg) { IsBusy = true; MMFWrite(MMFType.VALUE, msg); MMFWrite(MMFType.STATE, Role == MMFRole.Server ? "1" : "2"); if (Role == MMFRole.Client) MMFWrite(MMFType.CLIENT, ClientName); IsBusy = false; } private void MMFWrite(MMFType type, string msg) { long capacity = 1 << 10 << 10 << 10; var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}{type.ToString()}", capacity, MemoryMappedFileAccess.ReadWrite); lock (locker) { using (var accessor = mmf.CreateViewAccessor(0, capacity)) //视图 { accessor.Write(0, msg.Length); accessor.WriteArray<char>(sizeof(Int32), msg.ToArray(), 0, msg.Length); } } } private string MMFRead(MMFType type) { long capacity = 1 << 10 << 10 << 10; var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}{type.ToString()}", capacity, MemoryMappedFileAccess.ReadWrite); lock (locker) { using (var accessor = mmf.CreateViewAccessor(0, capacity)) { int strLen = accessor.ReadInt32(0); char[] chars = new char[strLen]; accessor.ReadArray<char>(sizeof(Int32), chars, 0, strLen); return new string(chars); } } } private void MMFDispose() { try { var mmf = MemoryMappedFile.OpenExisting($"{ServerName}STATE"); mmf.Dispose(); } catch (Exception) { } try { var mmf = MemoryMappedFile.OpenExisting($"{ServerName}VALUE"); mmf.Dispose(); } catch (Exception) { } try { var mmf = MemoryMappedFile.OpenExisting($"{ServerName}CLIENT"); mmf.Dispose(); } catch (Exception) { } } } }
标签:string,映射,MMFType,private,client,内存,msg,MMF,服务端 From: https://www.cnblogs.com/chase-zhou/p/16895060.html