保持Web服务调用之间的值

时间:2013-11-21 06:31:28

标签: c# .net web-services

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

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

4 个答案:

答案 0 :(得分:2)

根据您的说法,我认为您正在使用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 :(得分:0)

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

答案 2 :(得分:0)

如果您使用WCF创建服务,则可能需要考虑为主机使用SingleInstance模式。它允许您在呼叫之间保持数据。只有一个实例将为所有请求提供服务,您可以使用属性和属性在调用之间将数据保存在内存中。

WCF还支持会话,您可以保留相同的实例来为来自某个特定客户端的呼叫提供服务。

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

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

答案 3 :(得分:0)

您可以编写一个单独的类来保存您的引用。