我有一个使用windows服务的winform应用程序,我使用ChannelFactory连接到服务,问题是当我使用通道调用服务方法时,内存使用量增加了,并且方法执行后内存没有下降(即使在表单关闭之后),我调用了GC.Collect但没有改变。
通道创建类
public class Channel1
{
List<ChannelFactory> chanelList = new List<ChannelFactory>();
ISales salesObj;
public ISales Sales
{
get
{
if (salesObj == null)
{
ChannelFactory<ISales> saleschannel = new ChannelFactory<ISales>("SalesEndPoint");
chanelList.Add(saleschannel);
salesObj = saleschannel.CreateChannel();
}
return salesObj;
}
}
public void CloseAllChannels()
{
foreach (ChannelFactory chFac in chanelList)
{
chFac.Abort();
((IDisposable)chFac).Dispose();
}
salesObj = null;
}
}基类
public class Base:Form
{
public Channel1 channelService = new Channel1();
public Channel1 CHANNEL
{
get
{
return channelService;
}
}
}绞盘类
表格1:基础
private void btnView_Click(object sender, EventArgs e)
{
DataTable _dt = new DataTable();
try
{
gvAccounts.AutoGenerateColumns = false;
_dt = CHANNEL.Sales.GetDatatable();
gvAccounts.DataSource = _dt;
}
catch (Exception ex)
{
MessageBox.Show("Error Occurred while processing...\n" + ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
CHANNEL.CloseAllChannels();
_dt.Dispose();
//GC.Collect();
}
}发布于 2013-08-22 05:49:54
在使用ChannelFactory<T>方面,您是在正确的轨道上,但是您的实现有点偏离轨道。
ChannelFactory<T>为生成T类型的通道创建了一个工厂。这是一个相对昂贵的操作(与仅从现有工厂创建一个通道相比),并且通常在应用程序的每个生命周期(通常在开始时)完成一次。然后,您可以使用该工厂实例创建应用程序所需的多个通道。
通常,一旦我创建了工厂并缓存了它,当我需要调用服务时,我会从工厂获得一个通道,然后进行调用,然后关闭/中止该通道。
使用您发布的代码作为起点,我会这样做:
public class Channel1
{
ChannelFactory<ISales> salesChannel;
public ISales Sales
{
get
{
if (salesChannel == null)
{
salesChannel = new ChannelFactory<ISales>("SalesEndPoint");
}
return salesChannel.CreateChannel();
}
}
}请注意,我已经将salesObj替换为salesChannel (工厂)。这将在第一次调用工厂时创建工厂,并且每次都从工厂创建一个新的通道。
除非您有特殊的要求,否则我不会跟踪不同的通道,特别是如果遵循open/do方法/close方法。
在你的形式中,它看起来是这样的:
private void btnView_Click(object sender, EventArgs e)
{
DataTable _dt = new DataTable();
try
{
gvAccounts.AutoGenerateColumns = false;
ISales client = CHANNEL.Sales
_dt = client.GetDatatable();
gvAccounts.DataSource = _dt;
((ICommunicationObject)client).Close();
}
catch (Exception ex)
{
((ICommunicationObject)client).Abort();
MessageBox.Show("Error Occurred while processing...\n" + ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}上面的代码从通道中的工厂获得一个新的ISales通道,执行调用,然后关闭通道。如果发生异常,则在catch块中中止通道。
我将避免在通道上开箱即用Dispose(),因为框架中的实现是有缺陷的,如果通道处于错误状态,则会引发错误。如果您真的想使用Dispose()并强制垃圾收集,您可以--但是您必须解决WCF问题。Google会给你一些解决方案(google开始使用)。
https://stackoverflow.com/questions/18352838
复制相似问题