WCF медленный вызов ServiceHost.Open () - PullRequest
3 голосов
/ 19 января 2011

Этот вопрос похож на этот: Win32Exception @ ServiceHost.Open () для службы WCF .

У меня есть машина, которая работает очень медленно при вызове ServiceHost.Open ниже. Постоянно требуется около 7 секунд, чтобы открыть сервис каждый раз. Этот компьютер - мой домашний ящик, и он не является частью домена.

Я могу запустить тот же код в другом окне (моем рабочем окне), которое является частью домена, и хост службы открывается через 3-4 секунды при первом вызове, но если я запускаю снова запрограммируйте сервисный хост через 1 секунду или менее.

Я работал с поддержкой MS над этим, и мы создали журналы трассировки, и часть, в которой он висит, находится там, где выходит и пытается подключиться к домену, даже на машине, которая не является частью домена. И он получает «Указанный домен либо не существует, либо с ним нельзя связаться». исключение в журнале трассировки, и именно здесь все время съедается.

Но что действительно странно, так это то, что даже на моей рабочей машине, если я не подключен к домену (например, если я не нахожусь в моей рабочей сети и просто бегаю из дома), я все еще не получить задержку.

Я перестроил свою машину, используя 64-разрядную версию Windows 7, и произошло то же поведение (была запущена XP SP3, которую я восстановил, когда Windows 7, похоже, не устранила проблему).

Мне просто интересно, есть ли у кого-нибудь идеи о том, что может вызвать это. Кстати, если я отключу «Клиент для сетей Microsoft», время открытия ServiceHost будет равно 4 секундам, но это все же не так быстро, как раньше эта машина могла открывать службу. Каким-то образом он думает, что он должен быть частью домена или чего-то еще.

    static void RunServiceWithinEXE()
    {
        Uri baseAddress = new Uri("http://localhost:11111/Demo");
        ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);

        try
        {
            // Add a service endpoint
            serviceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                "CalculatorService");

            // Enable metadata exchange
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            serviceHost.Description.Behaviors.Add(smb);
            serviceHost.Opening += new EventHandler(serviceHost_Opening);
            serviceHost.Opened += new EventHandler(serviceHost_Opened);
            serviceHost.Open();
            Console.WriteLine("The service is ready.");

            // Close the ServiceHostBase to shutdown the service.
            serviceHost.Close();
        }
        catch (CommunicationException ce)
        {
            Console.WriteLine("An exception occured: {0}", ce.Message);
            serviceHost.Abort();
        }
    }

    static void serviceHost_Opened(object sender, EventArgs e)
    {
        TimeSpan timeToOpen = DateTime.Now - shOpening;
        Console.WriteLine("Time To Open: :" + timeToOpen.Seconds);
    }

    static void serviceHost_Opening(object sender, EventArgs e)
    {
        shOpening = DateTime.Now;
    }

Вот мой app.config, но у меня там нет никаких специальных настроек конфигурации безопасности для сервиса, только некоторые диагностические настройки для включения трассировки WCF.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <diagnostics>
            <messageLogging maxMessagesToLog="30000"
                    logEntireMessage="true"
                    logMessagesAtServiceLevel="false"
                    logMalformedMessages="true"
                    logMessagesAtTransportLevel="true">
                <filters>
                    <clear/>
                </filters>
            </messageLogging>
        </diagnostics>
    </system.serviceModel>

    <system.diagnostics>
        <sources>
            <source name="System.ServiceModel" switchValue="Warning, ActivityTracing" propagateActivity="true" >
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging" switchValue="Warning">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\Server.svclog" />
        </sharedListeners>
        <trace autoflush="true" indentsize="4">
            <listeners>
                <remove name="Default" />
                <add name="ScottsConsoleListener" type="System.Diagnostics.ConsoleTraceListener" />
                <add name="ScottsTextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Temp\DebugLog.txt" />
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>

Обратите внимание, что для моего определения службы требуется SessionMode (см. Ниже). Если я уберу требование SessionMode, я не получу задержек.

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required)]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);

        [OperationContract]
        double Subtract(double n1, double n2);

        [OperationContract]
        double Multiply(double n1, double n2);

        [OperationContract]
        double Divide(double n1, double n2);

        [OperationContract]
        string PrintName(string firstName, string lastName);

        [OperationContract]
        Point MakePoint(double x, double y);

    }
}

Ответы [ 4 ]

4 голосов
/ 20 января 2011

Ладно, я подозреваю, что вы используете привязку (WsHttpBinding), которая по умолчанию аутентифицирует своих вызывающих абонентов с использованием учетных данных Windows, если вы специально не запретите.

В коде размещения службы вы просто создаете экземпляр WsHttpBinding по умолчанию - в настройках или коде нет настроек для изменения поведения безопасности по умолчанию, в этом случае.

Только для целей тестирования: попробуйте изменить код хостинга вашего сервиса на:

 // Add a service endpoint
 serviceHost.AddServiceEndpoint(
            typeof(ICalculator),
            new WSHttpBinding(SecurityMode.None),  // pass in SecurityMode.None
            "CalculatorService");

Это эффективно отменит все настройки безопасности, например, ServiceHost больше не должен даже пытаться найти домен Windows для аутентификации вызывающих абонентов.

Изменит ли это какие-либо ваши наблюдения?

3 голосов
/ 22 января 2011

Оказывается, что, если я отключаю netbios на моих сетевых подключениях, я не получаю задержки на вызовы ServiceHost.Open. Я не уверен почему, но это, похоже, решило проблему.

Что странно, так это то, что когда я делал чистую установку XP, у меня не было задержек даже с включенным Netbios, поэтому я понятия не имею, почему это происходит с моей существующей установкой (я делал чистую установку на этой же компьютер, а затем восстановил мою резервную копию из образа для запуска этих тестов).

0 голосов
/ 06 ноября 2013

Кажется, у меня была такая же проблема.Длительность открытого вызова, вызванного исключением.Я гуглил для настройки параметров безопасности для службы Wcf.Нашел следующее решение, которое мне помогло:

Под элементом <wsHttpBinding> в файле Web.config введите следующую запись:

<security mode="None" />

Ссылка на услугуКлиент должен быть обновлен!

0 голосов
/ 14 февраля 2011

Также попробуйте остановить службу диспетчера автоматических подключений удаленного доступа. Для меня проблема сводилась к Dns.GetHostEntry (String.Empty) и этому сообщению http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/493d1b65-9ace-41de-b269-f178d27a8a1b

...