C# 碎片内存Ipc在控制台上触发EventHandler,在Wpf应用程序上失败

C# 碎片内存Ipc在控制台上触发EventHandler,在Wpf应用程序上失败,c#,wpf,event-handling,ipc,shared-memory,C#,Wpf,Event Handling,Ipc,Shared Memory,我正在练习将MMF实现为IPC,我已经通过wpf作为监听器进行了尝试,并设置了触发MMF的事件处理程序 现在,我已经将相同的setter代码移动到Wpf应用程序上的Wpf(在那之前,setter是控制台应用程序)中,我无法启动事件处理程序 我已经成功地实现了,我不确定这个实现是否正确,…我唯一能确定的是它发送数据、接收回复(实际上来自wpf)并触发事件(在控制台上) MMF类 public class MMFDepositT //: DiposiT<MyData> { pri

我正在练习将MMF实现为IPC,我已经通过wpf作为监听器进行了尝试,并设置了触发MMF的事件处理程序

现在,我已经将相同的setter代码移动到Wpf应用程序上的Wpf(在那之前,setter是控制台应用程序)中,我无法启动事件处理程序

我已经成功地实现了,我不确定这个实现是否正确,…我唯一能确定的是它发送数据、接收回复(实际上来自wpf)并触发事件(在控制台上)

MMF类

public class MMFDepositT //: DiposiT<MyData>
{
    private System.Threading.SendOrPostCallback callback;
    public event EventHandler<MemoryMappedDataReceivedEventArgs> DataReceived;
    private System.ComponentModel.AsyncOperation operation;

    public virtual string DipositChlName { get; set; }
    public virtual string DipositThrdName { get; set; }
    public virtual int DipositSize { get; set; }


    bool started;
    private bool disposed;
    public int ReadPosition { get; set; }
    public List<string> statusSet;
    private int writePosition;
    public int WritePosition
    {
        get { return writePosition; }
        set
        {
            if (value != writePosition)
            {
                this.writePosition = value;
                this.accessor.Write(WritePosition + READ_CONFIRM_OFFSET, true);
            }
        }
    }


    private const int DATA_AVAILABLE_OFFSET = 0;
    private const int READ_CONFIRM_OFFSET = DATA_AVAILABLE_OFFSET + 1;
    private const int DATA_LENGTH_OFFSET = READ_CONFIRM_OFFSET + 1;
    private const int DATA_OFFSET = DATA_LENGTH_OFFSET + 10;


    public MMFDepositT(string ctrIpcChannelNameStr, string ctrIpcThreadName, int ctrMMFSize)
    {

        this.DipositChlName = ctrIpcChannelNameStr;
        this.DipositSize = ctrMMFSize;
        this.DipositThrdName = ctrIpcThreadName;

        this.statusSet = new List<string>();
        try
        {
            mmf = MemoryMappedFile.CreateOrOpen(DipositChlName, DipositSize);
            accessor = mmf.CreateViewAccessor(0, DipositSize, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.ReadWrite);//if (started)
            //smLock = new System.Threading.Mutex(true, IpcMutxName, out locked);
            ReadPosition = -1;
            writePosition = -1;
            this.dataToSend = new List<byte[]>();

            this.callback = new System.Threading.SendOrPostCallback(OnDataReceivedInternal);
            this.operation = System.ComponentModel.AsyncOperationManager.CreateOperation(null);

            this.statusSet.Add("accessorOk & mmfOk");
        }
        catch (Exception e)
        {
            this.statusSet.Add("accessor Excep:-> " + e.Message);
        }



        //    return;
        //System.Threading.Thread t = new System.Threading.Thread(ReaderThread);
        //t.IsBackground = true;
        //t.Start();
        //this.started = true;
    }
    public void StartReader()
    {

        ////FieldInfo field = typeof(DipositValClF.ValueStrNameMax10SrV).GetField("Val");
        ////object[] attributes = field.GetCustomAttributes(typeof(MarshalAsAttribute), false);
        ////MarshalAsAttribute marshal = (MarshalAsAttribute)attributes[0];
        // Create named MMF

        if (started) return;
        if (ReadPosition < 0 || writePosition < 0)
            throw new ArgumentException();

        System.Threading.Thread t = new System.Threading.Thread(ReaderThread);
        t.IsBackground = true;
        t.Start();
        this.started = true;

    }
    private void ReaderThread(object stateInfo)
    {
        while (started)
        {
            // Checks if there is something to read.
            var dataAvailable = accessor.ReadBoolean(ReadPosition + DATA_AVAILABLE_OFFSET);
            if (dataAvailable)
            {
                // Checks how many bytes to read.
                int availableBytes = accessor.ReadInt32(ReadPosition + DATA_LENGTH_OFFSET);
                var bytes = new byte[availableBytes];
                // Reads the byte array.
                int read = accessor.ReadArray<byte>(ReadPosition + DATA_OFFSET, bytes, 0, availableBytes);

                // Sets the flag used to signal that there aren't available data anymore.
                accessor.Write(ReadPosition + DATA_AVAILABLE_OFFSET, false);
                // Sets the flag used to signal that data has been read. 
                accessor.Write(ReadPosition + READ_CONFIRM_OFFSET, true);

                MemoryMappedDataReceivedEventArgs args = new MemoryMappedDataReceivedEventArgs(bytes, read);
                operation.Post(callback, args);
            }

            System.Threading.Thread.Sleep(500);
        }
    }
    public void CloseReader()
    {
        started = false;
    }

    private System.Threading.Thread writerThread;
    private List<byte[]> dataToSend;
    private bool writerThreadRunning;
    public void Write(byte[] data)
    {
        if (ReadPosition < 0 || writePosition < 0)
            throw new ArgumentException();
        this.statusSet.Add("ReadWrite:-> " + ReadPosition + "-" + writePosition);
        // var s = (FsMomitorIPCCrier)data;


        lock (this.dataToSend)
            this.dataToSend.Add(data);

        if (!writerThreadRunning)
        {
            writerThreadRunning = true;
            writerThread = new System.Threading.Thread(WriterThread);
            writerThread.IsBackground = true;
            writerThread.Name = this.DipositThrdName;
            writerThread.Start();
        }
    }
    public void WriterThread(object stateInfo)
    {
        while (dataToSend.Count > 0 && !this.disposed)
        {
            byte[] data = null;
            lock (dataToSend)
            {
                data = dataToSend[0];
                dataToSend.RemoveAt(0);
            }

            while (!this.accessor.ReadBoolean(WritePosition + READ_CONFIRM_OFFSET))
                System.Threading.Thread.Sleep(500);

            // Sets length and write data.
            this.accessor.Write(writePosition + DATA_LENGTH_OFFSET, data.Length);
            this.accessor.WriteArray<byte>(writePosition + DATA_OFFSET, data, 0, data.Length);

            // Resets the flag used to signal that data has been read.
            this.accessor.Write(writePosition + READ_CONFIRM_OFFSET, false);
            // Sets the flag used to signal that there are data avaibla.
            this.accessor.Write(writePosition + DATA_AVAILABLE_OFFSET, true);
        }

        writerThreadRunning = false;
    }

    private void OnDataReceivedInternal(object state)
    {
        OnDataReceived(state as MemoryMappedDataReceivedEventArgs);
    }

    protected virtual void OnDataReceived(MemoryMappedDataReceivedEventArgs e)
    {
        if (e != null && DataReceived != null)
            DataReceived(this, e);
    }

    public virtual void Close()
    {
        //accessor.Dispose();
        //mmf.Dispose();
        //smLock.Close();
        started = false;
        if (accessor != null)
        {
            try
            {
                accessor.Dispose();
                accessor = null;
            }
            catch { }
        }

        if (this.mmf != null)
        {
            try
            {
                mmf.Dispose();
                mmf = null;
            }
            catch { }
        }

        disposed = true;
        GC.SuppressFinalize(this);
    }

    private System.IO.MemoryMappedFiles.MemoryMappedFile mmf;
    private System.IO.MemoryMappedFiles.MemoryMappedViewAccessor accessor;
}
公共类mmfdeposit/:DiposiT
{
private System.Threading.SendOrPostCallback回调;
接收到公共事件事件处理程序数据;
私有系统.ComponentModel.AsyncOperation操作;
公共虚拟字符串DipositChlName{get;set;}
公共虚拟字符串diposithrname{get;set;}
公共虚拟整数DipositSize{get;set;}
布尔开始;
私人住宅;
public int ReadPosition{get;set;}
公共列表状态集;
私有点写入位置;
公共点位置
{
获取{return writePosition;}
设置
{
if(值!=写位置)
{
this.writePosition=值;
this.accessor.Write(WritePosition+READ\u CONFIRM\u OFFSET,true);
}
}
}
私有常量int数据可用偏移量=0;
私有常量int READ\u CONFIRM\u OFFSET=数据可用\u OFFSET+1;
私有常量int数据长度偏移=读取确认偏移+1;
专用常量int DATA_OFFSET=数据长度_OFFSET+10;
公共MMFDepositot(字符串ctrIpcChannelNameStr、字符串CtripCthThreadName、int-ctrMMFSize)
{
this.DipositChlName=ctrIpcChannelNameStr;
this.DipositSize=ctrMMFSize;
this.diposithrname=ctrIpcThreadName;
this.statusSet=新列表();
尝试
{
mmf=MemoryMappedFile.CreateOrOpen(DipositChlName,DipositSize);
accessor=mmf.CreateViewAccessor(0,DipositSize,System.IO.MemoryAppedFiles.MemoryAppedFileAccess.ReadWrite);//如果(已启动)
//smLock=new System.Threading.Mutex(true,IpcMutxName,out-locked);
ReadPosition=-1;
writePosition=-1;
this.dataToSend=新列表();
this.callback=new System.Threading.SendOrPostCallback(OnDataReceivedInternal);
this.operation=System.ComponentModel.AsyncOperationManager.CreateOperation(null);
此.statusSet.Add(“accessorOk&mmfOk”);
}
捕获(例外e)
{
this.statusSet.Add(“访问者例外:->”+e.Message);
}
//返回;
//System.Threading.Thread t=新的System.Threading.Thread(ReaderThread);
//t、 IsBackground=true;
//t、 Start();
//this.started=true;
}
公共无效StartReader()
{
////FieldInfo field=typeof(DipositValClF.valuestrnamax10srv.GetField(“Val”);
////object[]attributes=field.GetCustomAttributes(typeof(MarshalAsAttribute),false);
////MarshalAsAttribute marshal=(MarshalAsAttribute)属性[0];
//创建命名的MMF
如果(开始)返回;
如果(读位置<0 | |写位置<0)
抛出新ArgumentException();
System.Threading.Thread t=新的System.Threading.Thread(ReaderThread);
t、 IsBackground=true;
t、 Start();
this.started=true;
}
私有void ReaderThread(对象状态信息)
{
while(启动)
{
//检查是否有要阅读的内容。
var dataAvailable=accessor.ReadBoolean(ReadPosition+DATA\u AVAILABLE\u OFFSET);
如果(数据可用)
{
//检查要读取的字节数。
int availableBytes=accessor.ReadInt32(ReadPosition+DATA\u LENGTH\u OFFSET);
var字节=新字节[可用字节];
//读取字节数组。
int read=accessor.ReadArray(读取位置+数据偏移量,字节,0,可用字节);
//设置用于表示不再有可用数据的标志。
accessor.Write(读取位置+数据可用偏移量,false);
//设置用于表示已读取数据的标志。
存取器。写入(读取位置+读取确认偏移量,真);
memorymappedatareceivedeventargs args=新的memorymappedatareceivedeventargs(字节,读取);
操作.Post(回调,args);
}
系统.线程.线程.睡眠(500);
}
}
公共阅读器()
{
开始=错误;
}
私有System.Threading.Thread writerThread;
私有列表数据发送;
私有布尔写线程运行;
公共无效写入(字节[]数据)
{
如果(读位置<0 | |写位置<0)
抛出新ArgumentException();
this.statusSet.Add(“读写:->”+ReadPosition+“-”+writePosition);
//var s=(FSMONITORIPCCRIER)数据;
锁(this.dataToSend)
this.dataToSend.Add(数据);
如果(!writerThreadRunning)
{
writerThreadRunning=true;
writerThread=new System.Threading.Thread(writerThread);
writerThread.IsBackground=true;
writerThread.Name=this.diposithrName;
writerThread.Start();
}
}
public void WriterThread(对象状态信息)
{
while(dataToSend.Count>0&&!this.disposed)
{
字节[]数据=null;
锁(数据发送)
{
data=dataToSend[0];
dataToSend.RemoveAt(0);
}
而(!this.accessor.ReadBoolean(WritePosition+READ\u CONFIRM\u OFFSET))
System.Threading.Thread.S
private System.Threading.SendOrPostCallback callback;
public event EventHandler<MemoryMappedDataReceivedEventArgs> DataReceived;
private System.ComponentModel.AsyncOperation operation;
        static bool MMfGetterTest1()
        {

            IpcAccessorSetting parCurSrv = new IpcAccessorSetting(IPChannelS.Debugger, IpcAccessorThreadNameS.DebuggerThrd, 0, 5000000);
            MMFinterComT DebuggerInterReciver=null;

                DebuggerInterReciver = new MMFinterComT(parCurSrv.Channel.ToString(), parCurSrv.AccThreadName.ToString(), 10000000);
                DebuggerInterReciver.ReadPosition = parCurSrv.AccessorSectorsSets.DepoSects.Getter.Read;
                DebuggerInterReciver.WritePosition = parCurSrv.AccessorSectorsSets.DepoSects.Getter.Write;
                DebuggerInterReciver.flagReciver1 = new EventWaitHandle(false, EventResetMode.ManualReset, DebuggerInterReciver.DipositThrdName);
                DebuggerInterReciver.flagReciver2 = new EventWaitHandle(false, EventResetMode.AutoReset, IpcAccessorThreadNameS.DebuggerThrdCurProj.ToString());
                DebuggerInterReciver.flagCaller1 = new EventWaitHandle(false, EventResetMode.ManualReset, IpcAccessorThreadNameS.DebuggerThrdCurProj.ToString());
                DebuggerInterReciver.flagCaller2 = new EventWaitHandle(false, EventResetMode.ManualReset, IpcAccessorThreadNameS.DebuggerThrdCurProj.ToString());
                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
               MbxTwDbSrv.Show(320, "Debugger Reciver Online ", "V", "Debugger Reciver Ready on\r\nDebuggerInterReciver.ReadPosition " + DebuggerInterReciver.ReadPosition + "\r\nDebuggerGetterepo.WritePosition " + DebuggerInterReciver.WritePosition)), System.Windows.Threading.DispatcherPriority.Normal);
                DebuggerInterReciver.flagCaller1.Set();
                DebuggerInterReciver.flagReciver1.WaitOne();
                DebuggerInterReciver.flagReciver1.Close();


            DebuggerInterReciver.flagReciver2.WaitOne(200);
            bool exit = false; int trys = 0;
            while(!exit)
            {


                DebuggerInterReciver.StartReader();
                System.Windows.Application.Current.Dispatcher.Invoke(new     Action(() =>
MbxTwDbSrv.Show(336, "Debugger Reciver Reading Failure ", "X", "Debugger Reciver read status on try: # "+ ++trys + " "+DebuggerInterReciver.IntercomStatus)), System.Windows.Threading.DispatcherPriority.Normal); 


                    DebuggerInterReciver.flagReciver2.WaitOne(700);
                    exit = DebuggerInterReciver.IntercomStatus==RobCs511C.AppMods.Selectors.IPC.IpcMMFinterComSF.MMFinterComTStatus.FinishedReading;
            }

            //DebuggerInterReciver.flagCaller.Set();
            DebuggerInterReciver.flagReciver2.Close();
            DebuggerInterReciver.flagCaller2.Set();

              var x = DebuggerInterReciver.ReadData.BytesToIpcCarier().AsDebggerCarier();
              System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                MbxTwDbSrv.Show(337, "Debugger Reciver OnReciveMessage: ", "V", "Debugger Reciver Has Recived Data: " + x.DvalStr +", Len= "+ x.DvalIntArr.Length)), System.Windows.Threading.DispatcherPriority.Normal);
              DebuggerInterReciver.reading = false;
            return true;

        }