在命名管道上使用WCF GetCallbackChannel进行内存泄漏

时间:2012-02-09 13:02:09

标签: wcf

我们有一个简单的wpf应用程序,它连接到本地计算机上运行的服务。我们使用命名管道进行连接,然后注册回调,以便稍后服务可以向客户端发送更新。

问题是每次调用回调时,我们都会在客户端应用程序中建立内存。

这是客户端连接服务的方式。

const string url = "net.pipe://localhost/radal";
_channelFactory = new DuplexChannelFactory<IRadalService>(this, new NetNamedPipeBinding(),url);

然后在线程池线程中我们循环执行以下操作直到我们连接

var service = _channelFactory.CreateChannel();
service.Register();

service.Register在服务器端看起来像这样

public void Register()
{
    _callback = OperationContext.Current.GetCallbackChannel<IRadalCallback>();
    OperationContext.Current.Channel.Faulted += (sender, args) => Dispose();
    OperationContext.Current.Channel.Closed += (sender, args) => Dispose();
}

存储此回调,当新数据到达时,我们在服务器端调用以下内容。

void Sensors_OnSensorReading(object sender, SensorReadingEventArgs e)
{
    _callback.OnReadingReceived(e.SensorId, e.Count);
}

参数是int和double。在客户端,这将按如下方式处理。

public void OnReadingReceived(int sensorId, double count)
{
    _events.Publish(new SensorReadingEvent(sensorId, count));
}

但是我们发现注释_event.Publish ...对内存使用没有任何影响。有没有人看到为什么这可能会泄漏内存的任何逻辑原因。到目前为止,我们已经使用分析器来跟踪问题,但无法找到正在构建的对象类型。

1 个答案:

答案 0 :(得分:1)

我现在可以部分回答这个问题。问题部分是由于我们试图变得聪明并且在另一个线程上打开连接然后将其传递回主gui线程。解决方案是不使用线程,而是使用调度计时器。它确实有一个缺点,即初始数据加载现在在GUI线程上,但我们还是没有加载所有这些。

然而,这不是整个解决方案(实际上我们没有完整的解决方案)。一旦我们转移到更好的分析器,我们发现构建的对象是超时处理程序,因此我们禁用了该功能。这对我们来说没关系,因为我们总是在对着本地主机运行,但我可以想象,对于使用远程服务的人来说,这将是一个问题。