+ MMFile: 增加多进程通信类

This commit is contained in:
Sunny 2021-09-05 16:42:19 +08:00
parent 25baf2f77e
commit 36058d5d55
9 changed files with 180 additions and 1 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -37,7 +37,7 @@ namespace Sunny.UI
{
[DefaultEvent("ItemClick")]
[DefaultProperty("Items")]
public sealed partial class UIListBox : UIPanel, IToolTip
public sealed class UIListBox : UIPanel, IToolTip
{
private readonly ListBoxEx listbox = new ListBoxEx();
private readonly UIScrollBar bar = new UIScrollBar();

View File

@ -766,6 +766,25 @@ namespace Sunny.UI
crc ^= 0xFFFFFFFF;
return crc.ToString("X").PadLeft(8, '0');
}
public static bool IsValidFileName(string name)
{
if (name.IsNullOrEmpty())
{
return false;
}
string[] errorStr = { "/", "\\", ":", ",", "*", "?", "\"", "<", ">", "|" };
foreach (var str in errorStr)
{
if (name.Contains(str))
{
return false;
}
}
return true;
}
}
/// <summary>

160
SunnyUI/Units/UMMFile.cs Normal file
View File

@ -0,0 +1,160 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2021 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UMMFile.cs
* :
* : V3.0
* : 2021-09-05
*
* 2021-09-05: V3.0.6
******************************************************************************/
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading;
namespace Sunny.UI
{
public sealed class MMFile : BackgroundWorkerEx, IDisposable
{
public string MapName { get; }
public int Capacity { get; }
public MMFile(string mapName, int capacity = 4096)
{
if (!FileEx.IsValidFileName(mapName))
{
throw new Exception("MapName is not valid.");
}
MapName = mapName;
WorkerDelay = 10;
Capacity = Math.Max(4096, capacity);
var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite);
using (var accessor = mmf.CreateViewAccessor(0, Capacity))
{
var value = accessor.ReadBoolean(0);
if (!value) accessor.Write(0, false);
}
}
public event MMFileEventHandler OnMessage;
protected override void DoWorker()
{
try
{
if (ExistsValue())
{
var message = Read();
OnMessage?.Invoke(this, new MMFileEventArgs(message.Source, message.Value));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public void Write(string dest, string message)
{
var mmf = MemoryMappedFile.CreateOrOpen(dest, Capacity, MemoryMappedFileAccess.ReadWrite);
using (var accessor = mmf.CreateViewAccessor(0, Capacity))
{
if (accessor.ReadBoolean(0))
{
Thread.Sleep(10);
}
var data = Encoding.Unicode.GetBytes(MapName);
accessor.Write(128, data.Length);
accessor.WriteArray(128 + 4, data, 0, data.Length);
data = Encoding.Unicode.GetBytes(message);
accessor.Write(1024, data.Length);
accessor.WriteArray(1024 + 4, data, 0, data.Length);
accessor.Write(0, true);
}
}
private Message Read()
{
Message message = new Message();
var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite);
using (var accessor = mmf.CreateViewAccessor(0, Capacity))
{
accessor.Write(0, false);
var len = accessor.ReadInt32(128);
var data = new byte[len];
accessor.ReadArray(128 + 4, data, 0, len);
message.Source = Encoding.Unicode.GetString(data);
len = accessor.ReadInt32(1024);
data = new byte[len];
accessor.ReadArray(1024 + 4, data, 0, len);
message.Value = Encoding.Unicode.GetString(data);
return message;
}
}
private bool ExistsValue()
{
var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite);
using (var accessor = mmf.CreateViewAccessor(0, Capacity))
{
return accessor.ReadBoolean(0);
}
}
internal struct Message
{
public string Source { get; set; }
public string Value { get; set; }
}
public void Dispose()
{
Stop();
try
{
var mmf = MemoryMappedFile.OpenExisting(MapName);
mmf.Dispose();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
~MMFile()
{
Dispose();
}
}
public delegate void MMFileEventHandler(object sender, MMFileEventArgs e);
public class MMFileEventArgs : EventArgs
{
public string Source { get; set; }
public string Value { get; set; }
public MMFileEventArgs(string source, string value)
{
Source = source;
Value = value;
}
}
}