Служба WCF, размещенная в Topshelf, закрывается очень долго - PullRequest
2 голосов
/ 30 сентября 2010

Я использую 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 завершил работу быстрее?

1 Ответ

1 голос
/ 02 октября 2010

Похоже, что Topshelf зависает при попытке завершить работу в 2.1.0.0.Это то, что мы должны рассмотреть.

Кроме того, вы всегда можете загрузить последние версии исполняемых файлов для веток Topshelf с http://teamcity.codebetter.com/.Войдите в систему как гость и найдите проект Masstransit, сборка находится в этом разделе.

...