首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ChannelFactory方法调用增加内存

ChannelFactory方法调用增加内存
EN

Stack Overflow用户
提问于 2013-08-21 08:47:36
回答 1查看 384关注 0票数 0

我有一个使用windows服务的winform应用程序,我使用ChannelFactory连接到服务,问题是当我使用通道调用服务方法时,内存使用量增加了,并且方法执行后内存没有下降(即使在表单关闭之后),我调用了GC.Collect但没有改变。

通道创建类

代码语言:javascript
复制
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;
}
}

基类

代码语言:javascript
复制
public class Base:Form
    {    
       public Channel1 channelService = new Channel1();        
       public Channel1 CHANNEL
       {
           get
           {
               return channelService;
           }
       }                  
    }

绞盘类

表格1:基础

代码语言:javascript
复制
 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();
            }
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-22 05:49:54

在使用ChannelFactory<T>方面,您是在正确的轨道上,但是您的实现有点偏离轨道。

ChannelFactory<T>为生成T类型的通道创建了一个工厂。这是一个相对昂贵的操作(与仅从现有工厂创建一个通道相比),并且通常在应用程序的每个生命周期(通常在开始时)完成一次。然后,您可以使用该工厂实例创建应用程序所需的多个通道。

通常,一旦我创建了工厂并缓存了它,当我需要调用服务时,我会从工厂获得一个通道,然后进行调用,然后关闭/中止该通道。

使用您发布的代码作为起点,我会这样做:

代码语言:javascript
复制
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方法。

在你的形式中,它看起来是这样的:

代码语言:javascript
复制
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开始使用)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18352838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档