等待WCF服务的最佳方法是什么?

5
我正在制作一个基础的自托管 WCF 服务,并且我想知道最好的等待接受请求的方法是什么?所有基本的教程都只使用 Console.ReadLine 等待用户按回车键退出。这对于真正的应用程序来说似乎不是很实用。我尝试了一个 while(true) 循环,但这会占用所有可用的 CPU 循环,所以这不是一个选项。我也尝试了 Thread.Sleep(0),但服务在睡眠时将无法接受请求,所以这也行不通。我相信有一些常见的方式可以使你的程序“停滞”以等待 WCF 请求; 有人知道怎么做吗?
我正在使用 C#、.NET 3.5 sp1。

值得注意的是,Thread.Sleep(0) 只会睡眠足够让其他线程运行的时间,然后就会返回。它不会等待任何一段时间。你可能本意是想使用 Thread.Sleep(Timeout.Infinite)(该值为-1),它可以无限期地阻塞,但是 ManualResetEvent 比这更好。 - Josh
3个回答

7
如果您在单独的线程中运行此代码(因为它是自托管的),一个简单的选项是使用ManualResetEvent。只需在WCF线程中调用manualResetEvent.WaitOne()。这将阻塞(就像Console.ReadLine一样),直到从单独的线程调用manualResetEvent.Set()。好处是您还可以拥有一个干净的机制来关闭服务。

太好了,这正是我想要的。我会尽快将其设置为已接受的答案。关机机制也是一个很好的帮助。 - bunglestink

7

如果一个应用程序没有用户界面,那么最好将其设置为Windows服务。您可以在服务的OnStart方法中设置WCF服务主机,然后在OnStop中关闭它。

示例通常使用控制台应用程序是因为它很容易演示,而不会让读者混淆与安装和运行服务无关的代码。但是,如果您的服务器不需要交互式UI,则建议研究Windows服务项目模板。


1
他提到这是一个自托管的服务。这有许多实际用途,包括将WCF服务放置在Windows Forms应用程序中进行托管等。通常需要设置一个线程来托管WCF服务,并使用一些技术(如等待句柄)来防止其关闭... - Reed Copsey
3
自托管服务简单来说就是使用WCF自启动而不是IIS或其他主机进程。对于非交互式的自托管服务,Windows服务是推荐的应用程序类型。 - Josh

1

在控制台应用程序中运行WCF服务很容易。但我无法让自托管的WCF在Windows服务中运行。可能有太多的安全问题需要处理。为了改进控制台应用程序服务托管示例,我创建了一个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方法中使用进程类执行此控制台应用程序,从而通过Windows服务运行它。感谢@Reed Copsey对WaitOne()的建议。

已测试并且可以从Process.Start()正常运行。在Windows 10中,只有当Windows服务在ServiceAccount.LocalSystem下运行时才能正常工作。否则,使用NET.TPC绑定时会遇到以下异常:System.ServiceModel.AddressAccessDeniedException at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()。你还需要在OnStop()重写中运行Process.Kill(),否则WCF服务将在Windows服务停止后仍然在系统上运行。 - Dan Randolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接