为什么InstanceContextMode.Single不起作用?

问题描述 投票:-1回答:2

我正在尝试让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();
}
wcf c++-cli
2个回答
0
投票

通常,您将ServiceBehaviorAttribute设置为实现服务的类的真实属性。我不是C ++ / CLI专家,但我猜你自己将CAutomation::typeid传递给ServiceHost构造函数,然后CAutomation就是你的服务类。那是对的吗?

如果是这样,那么它应该足以在ServiceBehaviorAttribute类上设置CAutomation


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;
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.