我正在制作一个基本的自托管WCF服务,我只是想知道在接受请求时让它等待的最佳方法是什么?我找到的所有基本教程都只使用Console.ReadLine来等待用户按Enter键退出。对于实际应用来说,这似乎不太实用。我试了一会儿(真的);循环,但这消耗了所有可用的CPU周期,因此它不是一个选项。我也试过Thread.Sleep(0),但服务在睡觉时不接受请求,所以这也行不通。我确信有一些常见的方法让你的程序“停顿”等待WCF请求;有谁知道怎么样?
我使用的是C#,.NET 3.5 sp1。
答案 0 :(得分:7)
如果你在一个单独的线程中运行它(因为它是自托管的),一个简单的选择就是使用ManualResetEvent。
只需在WCF线程中调用manualResetEvent.WaitOne();
即可。这将阻止(如Console.ReadLine),直到从单独的线程调用manualResetEvent.Set()
。
这里的好处是你可以有一个干净的机制来关闭服务。
答案 1 :(得分:7)
如果没有UI,真正的应用程序可能会更好地作为Windows服务。您可以在服务的OnStart方法中设置WCF服务主机,然后在OnStop中将其拆除。
示例通常使用控制台应用程序的原因是因为它很容易演示,而不会让读者混淆不相关的代码来安装和运行服务。但是,如果您的服务器不具备交互式UI,我建议您调查Windows服务项目模板。
答案 2 :(得分:0)
很容易让WCF服务在控制台应用程序中运行。我无法让自托管的WCF在Windows服务中工作。可能需要处理太多安全问题。为了改进console-app服务托管示例,我创建了一个AttachService方法,该方法在它自己的线程上运行。
public static AutoResetEvent manualReset;
// Host the service within this EXE console application.
public static void Main()
{
manualReset = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(AttachService);
//put Set() signal in your logic to stop the service when needed
//Example:
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
} while (key.Key != ConsoleKey.Enter);
manualReset.Set();
}
static void AttachService(Object stateInfo)
{
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), new Uri("net.tcp://localhost:9000/servicemodelsamples/service")))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
//Prevent thread from exiting
manualReset.WaitOne(); //wait for a signal to exit
//manualReset.Set();
}
}
我的目标是使用OnStart方法中的Process类从Windows服务执行此控制台应用程序。感谢@Reed Copsey对WaitOne()的建议。
答案 3 :(得分:-1)
使用BcakgroundWorker这是一个非常好的解决方案。