WCF使用匿名方法关闭连接

时间:2009-08-28 02:25:36

标签: c# wcf

在我们的项目中,我们使用以下代码进行WCF调用。

// In generated Proxy we have..
public static ICustomer Customer
{
 get
  {
    ChannelFactory<ICustomer> factory = new ChannelFactory<ICustomer>("Customer");
    factory.Endpoint.Behaviors.Add((System.ServiceModel.Description.IEndpointBehavior)new ClientMessageInjector());
    ICustomer channel = factory.CreateChannel();
    return channel;
  }
}

我们有Service Proxy类,其中包含

等方法
public static Datatable GetCustomerDetails(int id)
{
  return Services.Customer.GetCustomerDetails(id);
} 

public static void .SaveCustomerDetails (int id)
{
  Services.Customer.SaveCustomerDetails(id) ;
}

等...我们用它来进行商务电话。

最近我们发现我们需要“关闭”wcf连接,我们正试图找出这样做,而不要求我们的开发人员改变太多的代码。

请向我们提供一些有助于我们实现这一目标的建议

6 个答案:

答案 0 :(得分:6)

对于这种情况,可接受的“最佳做法”将是这样的:

// create your client
ICustomer channel = CreateCustomerClient();

try
{
   // use it
   channel.GetCustomerDetails() ....

   (more calls)

   // close it
   channel.Close();
}
catch(CommunicationException commEx)
{
   // a CommunicationException probably indicates something went wrong 
   // when closing the channel --> abort it
   channel.Abort();
}

通常,由于频道也实现了“IDisposable”,您可能只想简单地将其放入

using(ICustomer channel = CreateCustomerChannel()) 
{
   // use it
}

阻止 - 不幸的是,这可能会爆炸,因为很有可能在你的频道上试图调用.Close()时,你会得到另一个例外(在这种情况下将无法处理)。

我们的主持人Marc Gravell在这个主题上有一个有趣的blog post (don't(don't(use using)),有一个优雅的解决方案。

马克

答案 1 :(得分:1)

您还在当前方法中泄漏ChannelFactory<T>个对象。你也应该关闭它们。如果您在CreateChannel上使用静态ChannelFactory<T>方法,那么当客户端关闭时,您将获得工厂的自动关闭行为,这样可以帮助解决该问题。不幸的是,静态CreateChannel(string endpointConfigurationName)重载受到保护,因此您需要子类ChannelFactory<T>才能调用它。 (总的来说这可能不是那么糟糕。)

现在,如果您想要某个频道的“自动关闭”行为并且您正在使用会话合同(SessionMode = SessionMode.Required),则可以在{{{} {{}}中标记所有服务操作“IsInitiating = true, IsTerminating = true” 1}}属性。请注意,这将阻止您使用相同的ICustomer代理调用多个操作。如果可以使用,这可能是最简单的选择。

至于你的一般方法,对于一个属性做太多工作并不是一个好的设计,特别是当它涉及构建新的(昂贵的)对象和击中网络时。 WCF代理是很好的抽象,看起来像简单的接口实现,但它们不是无状态的,必须进行适当的管理。

答案 2 :(得分:0)

关闭连接的正确方法是将客户端放在使用块中,或者将关闭放在finally中。否则,只有在没有抛出异常时它们才会被关闭。

答案 3 :(得分:0)

信息in this question也可能有所帮助。

答案 4 :(得分:0)

不幸的是我们使用生成的代理方法来返回频道,我们在很多地方使用它。所以我想有一些方法可以“扩展”频道并在拨打电话后关闭连接(使用扩展方法)

答案 5 :(得分:0)

每次创建频道时都不要创建新的频道工厂。从性能的角度来看,这太可怕了!