C#远程处理后的服务器端清理

C#远程处理后的服务器端清理,c#,mono,remoting,C#,Mono,Remoting,我有一个在C#remoting(System.Runtime.remoting)上运行的简单客户机/服务器解决方案 然而,用于实际通信的MarshalByRef对象却让我感到困扰 在其构造函数中,它启动一个外部进程并添加OutputDataReceived eventhandler 每隔2秒,进程将向其标准输出写入数据,然后在eventhandler中检索并在那里使用 现在我的问题是如何在这个过程之后进行清理-问题是,它无限期地运行,所以我必须调用Kill()来停止它 我尝试在MarshalBy

我有一个在C#remoting(System.Runtime.remoting)上运行的简单客户机/服务器解决方案

然而,用于实际通信的MarshalByRef对象却让我感到困扰

在其构造函数中,它启动一个外部进程并添加OutputDataReceived eventhandler

每隔2秒,进程将向其标准输出写入数据,然后在eventhandler中检索并在那里使用

现在我的问题是如何在这个过程之后进行清理-问题是,它无限期地运行,所以我必须调用Kill()来停止它

我尝试在MarshalByRef对象的终结器中执行此操作,但是这会导致我的应用程序在尝试调用终结器时不时挂起

远程处理是作为单例设置的,因此应该由服务器端调用终结器,所以坦率地说,我觉得它有点奇怪,它不起作用

生成该进程的类实际上是我的MarshalByRef对象的一个字段,但这不应该有太大的变化

此外,该类在linux服务器上以mono运行,并从工具mpstat读取CPU负载

下面是困扰我的课程:

internal class CpuInfo
{
    private Regex parser = new Regex(@"\d{2}:\d{2}:\d{2}\s+(?<CpuID>\d{1,2}).*?(?<IdlePercentage>\d{1,2},\d{1,2})(\r|\n|$)", RegexOptions.Compiled | RegexOptions.Multiline);
    private Process proc;
    private IDictionary<int, long> cpuLoads;
    internal CpuInfo()
    {
        cpuLoads = new Dictionary<int, long>();
        proc = new Process();
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.CreateNoWindow = true;
        proc.StartInfo.Arguments = "-u -P ALL 2";
        proc.StartInfo.FileName = "mpstat";
        proc.StartInfo.RedirectStandardOutput = true;
        proc.EnableRaisingEvents = true;
        proc.OutputDataReceived += proc_OutputDataReceived;

        proc.Start();
        proc.BeginOutputReadLine();
    }

    void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Match match = parser.Match(e.Data);
        if (match.Success)
        {
            int cpuID = int.Parse(match.Groups["CpuID"].Value);
            string idleValue = match.Groups["IdlePercentage"].Value.Replace(',', '.');
            decimal idle = decimal.Parse(idleValue, CultureInfo.InvariantCulture);
            cpuLoads[cpuID] = (long)((100m - idle) * 100);
        }
    }

    ~CpuInfo()
    {
        proc.OutputDataReceived -= proc_OutputDataReceived;
        proc.Kill();
    }
}
内部类CpuInfo
{
私有正则表达式解析器=新正则表达式(@“\d{2}:\d{2}:\d{2}\s+(?\d{1,2})。*?(?\d{1,2}、\d{1,2})(\r{1,2})”,RegexOptions.Compiled | RegexOptions.Multiline);
私有进程进程;
私人词典;
内部CpuInfo()
{
cpuLoads=新字典();
proc=新流程();
proc.StartInfo.UseShellExecute=false;
proc.StartInfo.CreateNoWindow=true;
proc.StartInfo.Arguments=“-u-P ALL 2”;
proc.StartInfo.FileName=“mpstat”;
proc.StartInfo.RedirectStandardOutput=true;
proc.EnableRaisingEvents=true;
proc.OutputDataReceived+=proc_OutputDataReceived;
proc.Start();
进程BeginOutputReadLine();
}
void proc_OutputDataReceived(对象发送方,DataReceivedEventArgs e)
{
Match=parser.Match(即数据);
如果(匹配成功)
{
int cpuID=int.Parse(match.Groups[“cpuID”].Value);
字符串idleValue=match.Groups[“IdlePercentage”].Value.Replace(',',');
decimal idle=decimal.Parse(idleValue,CultureInfo.InvariantCulture);
cpuLoads[cpuID]=(长)((100米-空闲)*100);
}
}
~CpuInfo()
{
proc.OutputDataReceived-=proc_OutputDataReceived;
proc.Kill();
}
}

现在我自己解决了-我使用RemoteServices。封送服务器端和RemoteServices。连接客户端。这样,我的对象引用就存在于服务器端,我可以使用IDisposable很好地进行清理