我需要在ASP.NET中处理Web服务引用吗?

10

垃圾收集器是否清除Web服务引用,还是我需要在调用任何方法后调用服务引用的dispose方法?

5个回答

23

不要担心处理您的Web服务,您可以使用单例模式仅保留每个Web服务的单个实例。 Web服务是无状态的,因此可以安全地在Web服务器上的连接和线程之间共享。

这是一个Web服务类的示例,您可以使用它来保存对Web服务实例的引用。 这个单例是懒惰的和线程安全的。 建议您使单例懒惰,通过遵循相同的逻辑使它们也保持线程安全。 要了解更多信息,请阅读有关实现单例的C#深度文章。

还要记住,您可能会遇到WCF Web服务的问题。 我建议阅读WCF实例管理技术文章,特别是单例部分,以获取更多详细信息。

public static class WS
{
    private static object sync = new object();
    private static MyWebService _MyWebServiceInstance;

    public static MyWebService MyWebServiceInstance
    {
        get
        {
            if (_MyWebServiceInstance == null) 
            {
              lock (sync)
              {
                if (_MyWebServiceInstance == null)
                {
                    _MyWebServiceInstance= new MyWebService();
                }
              }
            }
            return _MyWebServiceInstance;
        }
    }
}

当您需要访问您的网络服务时,可以这样做:

WS.MyWebServiceInstance.MyMethod(...)

或者

var ws = WS.MyWebServiceInstance;
ws.MyMethod(...)

我已经在几个项目中成功使用了这种模式,而且效果很好。但正如tvanfosson在下面的评论中提到的那样,更好的策略是使用DI框架来管理您的Web服务实例。


1
使用单例将使任何使用它的东西难以测试。更好的方法是注入一个实例,或者更好的是使用包装了Web服务的Facade来隔离应用程序与服务的微小变化。然后让DI框架在请求完成后清理它。 - tvanfosson
@DanHerbert:有一件事我不懂:使用单例模式如何让你免于处理?你仍然需要处理你所创建的单例实例,不是吗? - displayName
@displayName 不需要处理单例。该实例在应用程序的生命周期内保持活动状态,并且 Web 服务创建的任何打开句柄将在应用程序停止时由操作系统自动清理。 - Dan Herbert
@DanHerbert 当两个线程调用单例时会发生什么...让我解释一下...对象上有一个锁,以使其线程安全。这是否意味着如果线程1调用webInstance,则线程2将等待线程1完成。还是锁纯粹用于实例的创建。假设您有10个调用者....锁是否意味着它们被链接在一起...或异步执行,我想您会明白我的问题,请告诉我如果不清楚。 - Seabizkit
@Seabizkit 这个锁只是为了创建元素,以确保10个同时调用者不会创建10个实例。您可以通过在额外的空值检查中包装“lock”块来轻微优化单例,以避免在单例已经被实例化的情况下创建锁。 - Dan Herbert
显示剩余7条评论

1

我认为DataService从Component继承了Dispose。


1

实现IDispose接口的对象应该手动释放以帮助垃圾回收器。

如果您的对象寿命短暂,请使用using块。对于可以保留的对象,请确保保留它们的对象在其自身被释放时也将其释放。


0

你在这里想要实现什么目标?

如果你担心性能问题,那么我更担心托管webservice的服务器响应速度和网络速度,因为它们会极大地影响你等待webservice调用完成的时间(除非它是异步的)。

MSDN上的示例没有调用“Dispose”,很明显垃圾收集器会完成它的工作,所以除非你正在处理每秒需要在内存中处理超过100,000条记录的实时系统,否则也许你不需要想出一种处理资源或管理内存的方法。


我的问题更多是从“应该”这个角度来考虑,而不是从“你必须”这个角度来考虑。我最关心的是内存泄漏,它会随着时间的推移逐渐降低性能。 - BeaverProj

0

我认为上面回答中Seabizkit的担忧是非常合理的。以下为引用:

@DanHerbert,当两个线程调用singleton时会发生什么...让我解释一下...对象上有一个锁,以使其线程安全。这是否意味着如果线程1调用accesses webInstance,那么线程2将等待线程1完成?或者锁纯粹是用于创建实例的。假设你有10个调用者...锁是否意味着它们被链接...或异步执行,我想你会明白我的问题,如果不清楚,请告诉我。-Seabizkit 2016年10月13日10:01 <

经过一些测试后,我可以确认当单个"客户端"对象被多个不同的线程使用时,您将无法获得任何良好的性能。 如果创建了十个线程并且它们都在使用相同的singleton'client',则它们必须排队等待所有先前的调用完成。

请查看并运行此C# Corner文章中的示例,以查看其证明: https://www.c-sharpcorner.com/article/increase-performance-with-an-object-pool-or-why-singleton-may-cause-performance/ 题为“使用对象池增加性能或为什么单例可能会导致性能问题”。

很抱歉打破单例Web服务用户的幻想。此外,你很难找到微软提供的将Web服务客户端“困”在单例中的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接