在 Web 服务中验证 Solr 连接

Authenticate Solr connection in web service

我正在开发一个 Web 服务,它应该获取一些数据,将它们用于查询,在 Solr 中搜索并 returns 适当的结果!它工作正常,但到目前为止我只需要它来初始化 Solr 一次,我得到了这个:

 private static bool initialized = false;

    [WebMethod]
    public XmlDocument getContributor(string name,string email)
    {
        if (!initialized)
        {
            Startup.Init<SolrSearchResult>("http://Host:44416/solr");
            initialized = true;
        }
        if (string.IsNullOrEmpty(email))
        {
            return SolrSearchResult.SearchData(name);
        }
        return SolrSearchResult.SearchDataWithEmail(name, email);
    }

但是我觉得当多人使用的时候,就不行了!我需要一个更聪明的方法来解决这个问题!如果有任何建议,我将不胜感激!

P.S:我看过 SampleSolrApp,在 Application_Start 中使用了 startup.init,但我不知道这里的等价物是什么。

当可能对您的 getContributor 方法进行多个并发调用时,确保 Startup.Init 永远不会被多次调用的一种方法是引入互斥锁来同步对该方法的访问代码块。

对于你的情况,我会首先引入一个静态对象来锁定:

private static readonly object syncRoot = new object();

然后将这部分代码包含在锁定语句中:

lock (syncRoot)
{
    // only 1 thread ever enters here at any time.

    if (!initialized)
    {
        Startup.Init<SolrSearchResult>("http://Host:44416/solr");
        initialized = true;
        // no more threads can ever enter here.
    }
}

lock关键字确保一个线程不会进入代码的临界区,而另一个线程在临界区。如果另一个线程试图进入一个被锁定的代码块,它将等待直到对象被释放。

作为旁注;您可以使用一种小技巧来优化此代码,进一步称为 双重检查锁定 ,它可以避免每次调用 getContributor 时获取锁定的小性能成本:

// check to see if its worth locking in the first place.
if (!initialized)
{
    lock (syncRoot)
    {
        // only 1 thread ever enters here at any time.

        if (!initialized)
        {
            Startup.Init<SolrSearchResult>("http://Host:44416/solr");
            initialized = true;
            // no more threads can ever enter here.
        }
    }
}

initialized 永远不需要变成 false 并且您以后不需要 Startup.Init 变成 运行 时,无论出于何种原因,这都有效。否则,您可能 运行 按原样使用此代码会遇到问题。