C#远程处理后的Serverside清理

时间:2010-02-18 10:19:21

标签: c# mono remoting

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

用于实际通信的MarshalByRef对象会让我感到麻烦。

在其构造函数中,它启动一个外部进程并添加OutputDataReceived事件处理程序。

该过程每2秒钟将数据写入其标准输出,然后我在我的事件处理程序中检索并在那里使用。

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

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

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

产生进程的类实际上是我的MarshalByRef对象的一个​​字段,但实际上不应该改变很多。

该类在Linux服务器上以单声道运行,并从工具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();
    }
}

1 个答案:

答案 0 :(得分:0)

现在自己想出来 - 我使用RemoteServices.Marshal服务器端和RemoteServices.Connect客户端。这样我的对象引用就存在于服务器端,我可以很好地使用IDisposable进行清理。