WCF 关闭服务主机时等待操作完成
本文关键字:等待 操作 主机 服务 WCF | 更新日期: 2023-09-27 17:56:38
我创建了一个WCF SOAP服务器,其操作需要一些时间才能执行:
[ServiceContract]
public interface IMyService
{
[OperationContract]
string LongRunningOperation();
}
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = false,
InstanceContextMode = InstanceContextMode.Single)]
class MyService : IMyService
{
public string LongRunningOperation()
{
Thread.Sleep(20000);
return "Hey!";
}
}
class Program
{
static void Main(string[] args)
{
MyService instance = new MyService();
ServiceHost serviceHost = new ServiceHost(instance);
BasicHttpBinding binding = new BasicHttpBinding();
serviceHost.AddServiceEndpoint(typeof(IMyService), binding, "http://localhost:9080/MyService");
serviceHost.Open();
Console.WriteLine("Service running");
Thread.Sleep(10000);
serviceHost.Close();
Console.WriteLine("Service closed");
Thread.Sleep(30000);
Console.WriteLine("Exiting");
}
}
服务主机被打开,10 秒后我关闭它。
调用 serviceHost.Close() 时,当前连接的所有客户端(等待 LongRunningOperation 完成)都会立即断开连接。
是否等待以更简洁的方式关闭服务主机?也就是说,我想禁用服务侦听器,但也要等待所有当前连接的客户端完成(或指定最大超时)。
我很惊讶调用ServiceHost.Close不会让LongRunningOperation完成。
整个架构的设置是为了让事情有时间优雅地关闭(例如,关闭和中止转换之间的差异)。根据MSDN文档:
此方法会导致 通信对象优雅地 从任何状态转换,除了 关闭状态,进入关闭状态 州。关闭方法允许任何 之前要完成的未完成工作 返回。
此外,服务主机上还有一个关闭超时,正是为此。您是否尝试过将关闭超时设置为大于 20 秒?(根据Reflector,ServiceHost的默认关闭超时是10秒...
原则上,我认为以下内容应该是可能的,尽管我尚未实现它以确认所有细节:
- 实现自定义 IOperationInvoker包装调度程序的法线操作调用程序(您需要一个
IServiceBehavior
在构建服务调度程序运行时时安装包装的调用程序) - 自定义调用程序将主要委托给真正的调用程序,但也将提供"看门人"功能可转身离开当服务主机处于要关闭。
- 它还将跟踪仍在进度并设置上次操作调用完成或超时时的事件。
- 然后,主宿主线程将在调用
serviceHost.Close()
之前等待调用程序的"全部完成"事件。
你正在做的事情对我来说似乎都是错误的。服务主机不应突然关闭。这是一项服务,应保持可用。没有客户的参与,就没有真正的方法可以优雅地关闭。当我优雅地说接近时,从客户的角度来看,这也是主观的。
所以我认为我根本不了解您的要求,但是一种方法是实现发布/订阅模式,当主机准备好关闭时,通知所有订阅者此事件,以便每个客户端都可以关闭所有连接。您可以在此处阅读有关此内容的更多信息 http://msdn.microsoft.com/en-us/magazine/cc163537.aspx
同样,这种托管服务的方法不是标准的,这就是为什么您发现很难找到解决此特定问题的方法的原因。如果您可以详细说明您的用例/使用场景,那么找到真正的解决方案可能会有所帮助。
您正在描述客户端功能。听起来您应该包装服务主机对象,然后在代理"关闭"时拒绝新请求。在处理完所有呼叫之前,不会关闭真正的服务主机。
您还应该查看异步 CTP。将这种逻辑放在消费者端的"Task"对象中,使用即将推出的 TaskCompletionSource 类会容易得多。
从 dnrtv 查看此视频。这不是关于 wcf,而是关于即将推出的异步语言和类支持。