为什么InstanceContextMode.Single不工作?

时间:2018-06-18 17:19:16

标签: wcf c++-cli

我试图让WCF服务在InstanceContextMode.Single中运行,这样所有请求都可以共享相同的服务状态。但是,当我尝试使用此行为启动服务时,我仍然可以看到每个请求都会调用服务的构造函数。我无法找到更新ServiceBehaviorAttribute的快捷方法,这就是我替换它的原因(InstanceContextMode的默认值不是Single)。好像我们启动它时有一个实例,然后是稍后进入的所有请求的另一个实例。什么想法可能会出错?

/// <summary>Constructor</summary>
CAutomation::CAutomation()
{
    //TODO:  pull from config
    m_Host = gcnew ServiceHost(CAutomation::typeid, gcnew Uri("http://localhost:8001/GettingStarted"));

    // add a service endpoint.
    m_Host->AddServiceEndpoint(IAutomation::typeid, gcnew WSHttpBinding(), "Automation");

    // add behavior
    ServiceMetadataBehavior^ smb = gcnew ServiceMetadataBehavior();
    smb->HttpGetEnabled = true;
    m_Host->Description->Behaviors->Add(smb);

    // enforce single instance behavior
    m_Host->Description->Behaviors->RemoveAt(0);
    ServiceBehaviorAttribute^ sba = gcnew ServiceBehaviorAttribute();
    sba->InstanceContextMode = InstanceContextMode::Single;
    m_Host->Description->Behaviors->Add(sba);
}

/// <summary>Starts the automation service.</summary>
void CAutomation::Start()
{
    m_Host->Open();
}

2 个答案:

答案 0 :(得分:0)

通常,您将ServiceBehaviorAttribute设置为实现服务的类的真实属性。我不是C ++ / CLI专家,但是我想由于您将CAutomation::typeid传递给ServiceHost构造函数,因此CAutomation是您的服务类。正确吗?

如果是这样,那么在ServiceBehaviorAttribute类上设置CAutomation就足够了。

答案 1 :(得分:0)

Igor Labutin向我指出了正确的方向,但真正的问题是,至少在[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode::Single)]中,创建服务宿主对象将创建其类型传递给其构造函数的类的实例。 。基本上,ServiceHost对象不应该是CAutomation类的构造函数。我将该对象从该构造函数之外移到了另一个对象,该对象负责何时应该启动服务并纠正了问题。我将粘贴一些示例代码,以帮助说明更好的方法。

class Program
{
    static void Main(string[] args)
    {
        Uri address = new Uri
            ("http://localhost:8080/QuickReturns/Exchange");
        ServiceHost host = new ServiceHost(typeof(TradeService);
        host.Open();
        Console.WriteLine("Service started: Press Return to exit");
        Console.ReadLine();
     }
 } 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,
    ReturnUnknownExceptionsAsFaults=true)]
public class TradeService : ITradeService
{
    private Hashtable tickers = new Hashtable();
    public Quote GetQuote(string ticker)
    {
        lock (tickers)
        {
            Quote quote = tickers[ticker] as Quote;
            if (quote == null)
            {
                // Quote doesn't exist
                throw new Exception(
                    string.Format("No quotes found for ticker '{0}'",
                    ticker)); 
            }
            return quote;
        }
    }
    public void PublishQuote(Quote quote)
    {
        lock (tickers)
        {
            Quote storedQuote = tickers[quote.Ticker] as Quote;
            if (storedQuote == null)
            {
                tickers.Add(quote.Ticker, quote);
            }
            else
            {
                tickers[quote.Ticker] = quote;
            }
        }
    }
}