我试图让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();
}
答案 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;
}
}
}
}