【问题标题】:Keeping a value between web service calls在 Web 服务调用之间保持一个值
【发布时间】:2014-12-18 18:45:06
【问题描述】:

我需要在 Web 服务端的每个 Web 服务调用之间保留一个字符串列表。简单地说,这个列表不应该在每次 Web 服务调用进行后丢弃。它的生命周期应该随着 Web 服务应用程序的启动和 Web 服务应用程序的停止而结束。类似于应用程序中的静态变量。

如何在 C#.net web-service 中实现这样的东西?

【问题讨论】:

  • 只是想确认一下:在每个web服务调用之间保留一个字符串列表——你的意思是当每个客户端发送请求时你应该创建字符串列表并发送给客户端?
  • @DWHelper:不,你认为我在网络服务中有一个 IP 地址列表。因此,在每个 Web 服务调用中,它需要检查调用是否来自列表中的此 IP 之一。因此,此 IP 地址列表应在每个 Web 服务调用之间共享。我可以使用数据库或文本文件来存储这个 IP 列表。但就我而言,我需要更高的效率。所以,我想存储在内存中(听起来像是在全局内存中)
  • 尝试实现 WCF 回调合约,这将负责客户端管理。 codeproject.com/Articles/29027/…中的示例项目
  • 使用服务时,将数据保存在内存中有时可能不如您预期的那么可靠,尤其是当您可能不知道服务何时启动/关闭时(例如,可能会创建/销毁 WCF 服务实例根据需要处理传入的操作请求,因此可能不会在请求之间共享内存)。如果您需要请求之间的状态,最好将其放在可靠的地方,例如数据库或文件。
  • @ToddBowles:但在这种情况下,我主要担心效率。没有时间从数据库或文本文件中读写。因为大约有 100 个会话做同样的事情。所以可能会有瓶颈。您如何看待保存在 Web 应用程序缓存中?

标签: c# .net web-services


【解决方案1】:

根据您所说,我认为您使用的是 ASP.NET Web 服务(如果我错了,请纠正我)。

您可以创建一个静态类,其中包含某种类型的集合(Dictionary、HashSet 等),然后您可以使用这些集合来存储您的信息。好处是这会非常快,坏处是每次你的服务的 AppDomain 被回收时,你的数据都会被清除。 如果这不是问题,那么这可能是最简单的选择。

您可以阻止 IIS 回收您的 ASP.NET 进程,但回收是有原因的,除非您知道会产生什么影响,否则我不建议这样做。

关于实际的课程,这样的事情会起作用:

public static class GlobalState
{
    private static HashSet<string> _ipAddresses;
    public static HashSet<string> IPAddresses
    {
        get
        {
            if (_ipAddresses == null) _ipAddresses = new HashSet<string>();
            return _ipAddresses
        }
    }
}

那么当你想使用它时:

*** some code
if (GlobalState.IPAddresses.Contains(ipAddress))
*** some more code

或者您想利用静态集合。

更新: 我已经做了一些进一步的调查,看起来如果您希望 AppDomain 重新启动之间的持久性,您的选择是有限的。可能是某种数据库或磁盘。

另外,我上面给出的解决方案虽然简单,但从可测试性的角度来看很差,并且没有考虑到同时对服务进行多次多次调用而可能发生的并发问题时间。

我建议使用以下内容:

public class Service : System.Web.Services.WebService
{
    public Service()
        : this(InMemoryTokensProvider.GetInstance())
    {

    }

    public Service(TokensProvider statePersister)
    {
        _tokens = statePersister;
    }

    private TokensProvider _tokens;

    [WebMethod]
    public string ServiceCall() 
    {
        if (_tokens.Contains("TestToken"))
        {
            return "Token was present!";
        }
        else
        {
            _tokens.Add("TestToken");
            return "Token was added!";
        }
    }
}

public interface TokensProvider
{
    void Add(string token);
    bool Contains(string token);
}

public class InMemoryTokensProvider : TokensProvider
{
    private static InMemoryTokensProvider _instance;
    public static TokensProvider GetInstance()
    {
        if (_instance == null) _instance = new InMemoryTokensProvider();

        return _instance;
    }

    private HashSet<string> _tokens = new HashSet<string>();
    public void Add(string token)
    {
        lock (_tokens)
        {
            _tokens.Add(token);
        }
    }

    public bool Contains(string token)
    {
        lock (_tokens)
        {
            return _tokens.Contains(token);
        }
    }
}

【讨论】:

  • +1 了解我的问题。 AppDomain 在什么情况下被回收?可以在应用程序破坏的同时进行吗?如果那将是数据不可用的问题。在 Windows 应用程序中。在 asp.net Web 应用程序的应用程序级别中应该有一种适当的方式来存储数据。不是吗?
  • @NayanaAdassuriya IIS 不会以某种方式回收 AppDomain 以使当前请求失败,但它肯定可以在请求之间进行,基本上任何时候感觉资源使用需要重新评估。看起来你需要比我最初写的更持久的东西,所以我去看看然后回复你。您可能可以利用 Application 对象或 ASP.NET 缓存架构。
【解决方案2】:

其实我觉得你可以定义一个基于类的或者静态的全局变量 Dictionary:Key是IP地址,而另一个字符串保存你的值。您可以使用 ContainsKey 或相关方法检查请求 IP 是否存在并从字典中返回值,否则请将新的 IP 地址添加到字典中。

【讨论】:

  • 你能给我举个例子吗?
  • 存储在缓存中怎么样?看stackoverflow.com/questions/12857899/store-list-in-global-asax的回答
  • 对不起,我没想到你使用的是ASP.NET应用程序:如果使用它,你可以将它保存到Application而不是Cache中,因为缓存会在一段时间后过期。
  • 感谢您的想法。 save that into the Application 是什么意思?
  • Application["xx"] = 字典 Application_Start 事件中的实例。
【解决方案3】:

如果您使用 WCF 创建服务,您可能需要考虑为您的主机使用 SingleInstance 模式。它将允许您在通话之间保留数据。只有一个实例会处理所有请求,您可以使用属性和属性在调用之间将数据保存在内存中。

WCF 还支持会话,您可以保留相同的实例来服务来自一个特定客户端的调用。

在每种情况下,吞吐量都会受到影响,除非您授权多线程访问您的实例。然后你必须处理并发问题。

另一种可能且可能更好的解决方案是使用持久存储在多次调用之间保存数据。

【讨论】:

    【解决方案4】:

    你可以编写一个单例类来保存你的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多