Я использую Topshelf для размещения службы WCF в качестве службы Windows.Даже когда я просто запускаю консоль, после отправки ей комбинации клавиш Ctrl-C требуется исключительно долгое время, и это отражается при запуске в качестве службы.На моем локальном компьютере требуется 1 мс для вызова svcHost.Close (new TimeSpan (0)), но 10240 мс между концом моего метода Stop, который вызывает Topshelf, и после того, как код выпадает из метода Runner.Host ().Это не очень хорошо, но на производственном сервере, который я пробовал, второе значение - 70-е.Это значит, что ОС Windows предоставит услугу более 30 секунд, прежде чем решит, что она является мусором.
Вот мой код Topshelf и код сервиса.Я много урезал, чтобы удалить ведение журнала и обработку исключений в Log4Net, потому что я убедился, что исключения не возникают.
public class Service
{
private ServiceHost svcHost;
public void Start()
{
string bindUri = "net.tcp://MyMachineName:10000";
svcHost = new ServiceHost(typeof(MyServiceClass));
svcHost.AddServiceEndpoint(typeof(IMyService), new NetTcpBinding("tcp"), bindUri);
svcHost.Description.Behaviors.Add(new LoggerBehavior());
svcHost.Open();
}
public void Stop()
{
svcHost.Close(new TimeSpan(0));
svcHost = null;
}
}
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
var cfg = RunnerConfigurator.New(c =>
{
c.ConfigureService<Service>(s =>
{
s.Named("MyServiceName");
s.HowToBuildService(x => new Service());
s.WhenStarted(service => service.Start());
s.WhenStopped(service =>
{
sw.Start();
service.Stop();
sw.Stop();
Console.WriteLine("Stop Time: {0}ms", sw.ElapsedMilliseconds); // usually 1-2ms
sw.Reset();
sw.Start();
});
});
c.RunAsLocalSystem();
c.SetDescription("Runs MyServiceName.");
c.SetDisplayName("MyServiceName");
c.SetServiceName("MyServiceName");
});
Runner.Host(cfg, args);
sw.Stop();
// ~10 seconds on my machine, ~70s on a production server!
Console.WriteLine("Finish Time: {0}ms", sw.ElapsedMilliseconds);
}
}
Чуть более 10 секунд и чуть более 70 секунд кажутся слишком большими "defaulty ", поэтому я искал верхние и нижние значения таймаутов, чтобы установить как можно более низкие значения, но ни один из них, похоже, не приносит никакой пользы.Вот мой код app.config.
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="tcp"
maxReceivedMessageSize="52428800"
transferMode="Buffered"
openTimeout="0:00:01"
sendTimeout="0:00:01"
receiveTimeout="0:00:01"
closeTimeout="0:00:01">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100" />
<serviceTimeouts transactionTimeout="0:00:01" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MyApp.MyServiceClass" behaviorConfiguration="MyServiceBehavior">
<host>
<timeouts openTimeout="0:00:01" closeTimeout="0:00:01" />
</host>
</service>
</services>
</system.serviceModel>
Итак, что я могу сделать, чтобы WCF завершил работу быстрее?