Мне нужна моя размещенная служба WAS (PerCall, Concurrency.Multiple), чтобы корректно завершать работу / перезапускать, но любые неактивные (но открытые) прокси-серверы клиента будут блокировать корректное отключение службы.
Я ожидал, что receiveTimout включит и выбросит неактивные сеансы, но похоже, что это не работает таким образом.
При перезапуске IIS / WAS будет вызываться ServiceHost.BeginClose с тайм-аутом закрытия, равным TimeSpan.MaxValue.
Мне нужно разрешить долго живущие клиентские прокси (которые я не могу контролировать) с помощью netTcpBinding, поскольку пропускная способность и низкая задержка являются обязательными.
Я воспроизвел проблему ниже и был бы раддля любых обходных путей и помощи относительно проблемы.
using System;
using System.ServiceModel;
namespace Test
{
[ServiceContract(Name = "MyService", SessionMode = SessionMode.Allowed)]
public interface IHelloWorldService
{
[OperationContract]
void PrintHelloWorld();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HellowWorldService : IHelloWorldService
{
[OperationBehavior]
public void PrintHelloWorld()
{
Console.WriteLine("Hello world!");
}
}
public class ThaProgram
{
static void Main(string[] args)
{
const string ServiceAddress = "net.tcp://localhost:12345/HelloWorld";
var netTcpBinding = new NetTcpBinding(SecurityMode.None, false);
netTcpBinding.ReceiveTimeout = TimeSpan.FromSeconds(3);
var serviceHost = new ServiceHost(typeof(HellowWorldService), new Uri("net.tcp://localhost:12345"));
serviceHost.AddServiceEndpoint(typeof(IHelloWorldService), netTcpBinding, ServiceAddress);
serviceHost.Open();
Console.WriteLine("Service host state: {0}", serviceHost.State);
netTcpBinding.ReceiveTimeout = TimeSpan.FromSeconds(10);
var channel = new ChannelFactory<IHelloWorldService>(netTcpBinding, ServiceAddress).CreateChannel();
channel.PrintHelloWorld();
// Uncomment to make everything work (then the session will be closed before the service enters the closing state)
// Thread.Sleep(4000);
// Simulate application pool shutdown
var asyncResult = serviceHost.BeginClose(TimeSpan.MaxValue, null, null);
Console.WriteLine("Service host state: {0}", serviceHost.State);
serviceHost.EndClose(asyncResult);
Console.WriteLine("Service host state: {0}", serviceHost.State);
Console.WriteLine("Hit Enter to close the application");
Console.ReadLine();
}
}
}