Q&A 20090607

Q:
Mutex失效的问题
Mutex,它只对一个线程授予对共享资源的独占访问权限, 一般可以用来做单进程启动的控制代码, 但是下面这段代码有时就会失效:
 bool isCreatedNew;
 Mutex mutex = new Mutex(false, @"Global\RealTime_CmdCollection", out isCreatedNew))
 if (isCreatedNew == false)
        return;
有时就会发现, 同一个Exe(Release版本的)运行两个, 第二个进程的isCreatedNew 依然为true, 就没有了单进程控制的能力, 这个如何解释?
应答:这里的metux是一个临时变量 在这几行代码以后没有代码引用, 在程序内存不够的时候, CLR会执行内存回收, 就会把这个对象回收掉, 解决这个问题有两个方法, 第一, 使用using来使用Mutex , 第二, 在程序退出之前调用mutex的dispose方法,这样CLR就会发现这个对象在下面的代码中还有使用, 就不会销毁这个代码了.
 

Q:
终于找到内存泄漏的原因了 , 我自己吧异步进程吊起来了. 导致异步读无法结束, 导致无法释放句柄
找到这个bug的感觉是: 写代码, 需要谨慎, 谨慎, 再谨慎, 每写一行代码, 这行代码干什么的, 上下的顺序, 会出什么异常, 都要搞清楚. 不然, 太容易出问题, 因为正确的路只有一条, 而其他任何一条道路都是错误的, 犯错误太容易了, 而做好就需要12分的谨慎.
//改了以后
 private void ConsoleOutputCallback(IAsyncResult ar)
        {
            try
            {
                if (this.Tcp != null && this.Tcp.Connected)
                {
                    Stream outputStream = ar.AsyncState as Stream;
                    int bytesRead = outputStream.EndRead(ar);
                    if (bytesRead > 0)
                    {
                        this.Tcp.Send(this.AsynBuffer, bytesRead);
                        this.ConsoleProcess.StandardOutput.BaseStream.BeginRead(this.AsynBuffer, 0, 0x2000, new AsyncCallback(this.ConsoleOutputCallback), outputStream);
                    }
                }
            }
            catch (Exception ex)
            {
                ServiceEntryPoint.Instance.WriteLog(ex.ToString(), EventLogEntryType.Warning, 0);
                this.WriteToClient(ex.Message);
                this.Close();
            }
        }

//原来的版本
 private void ConsoleOutputCallback(IAsyncResult ar)
        {
            try
            {
                Stream outputStream = ar.AsyncState as Stream;
                int bytesRead = outputStream.EndRead(ar);
                if (bytesRead > 0)
                {
                    if (this.Tcp != null && this.Tcp.Connected)
                    {
                        this.Tcp.Send(this.AsynBuffer, bytesRead);
                        this.ConsoleProcess.StandardOutput.BaseStream.BeginRead(this.AsynBuffer, 0, 0x2000, new AsyncCallback(this.ConsoleOutputCallback), outputStream);
                    }
                }
            }
            catch (Exception ex)
            {
                ServiceEntryPoint.Instance.WriteLog(ex.ToString(), EventLogEntryType.Warning, 0);
                this.WriteToClient(ex.Message);
                this.Close();
            }
        }

原文地址:https://www.cnblogs.com/dunnice/p/1498276.html