Почему WCF не поддерживает тайм-ауты на стороне службы? - PullRequest
20 голосов
/ 12 февраля 2011

Недавно мы обнаружили, что WCF не поддерживает операции тайм-аута на стороне службы (примечание: служба сторона, а не сторона клиента). В то время как клиент отключается по истечении указанного времени, наше тестирование показало, что для netNamedPipeBinding, netTcpBinding и basicHttpBinding ни одно из указанных нами тайм-аутов не приведет к остановке работы службы после ее вызова. Ниже приведены конкретные конфигурации привязок, которые мы попробовали:

<bindings>
  <netNamedPipeBinding>
    <binding name="TestServiceBindingConfigurationNamedPipe"
             receiveTimeout="00:00:05"
             sendTimeout="00:00:05"
             closeTimeout="00:00:05"
             openTimeout="00:00:05" />
  </netNamedPipeBinding>
  <netTcpBinding>
    <binding name="TestServiceBindingConfigurationTcp"
             receiveTimeout="00:00:05"
             sendTimeout="00:00:05"
             closeTimeout="00:00:05"
             openTimeout="00:00:05" />
  </netTcpBinding>
  <basicHttpBinding>
    <binding name="TestServiceBindingConfigurationBasicHttp"
             receiveTimeout="00:00:05"
             sendTimeout="00:00:05"
             closeTimeout="00:00:05"
             openTimeout="00:00:05" />
  </basicHttpBinding>
</bindings>

Наша реализация службы тестирования выглядит следующим образом:

public class TestServiceImpl : ITestService
{
    public TestResult TestIt(TestArgs args)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();

        // this is a contrived example, but it shows that WCF never stops this thread
        while (true)
        {
            Console.WriteLine("{0}> I'm running forever...", stopwatch.Elapsed);
        }

        return new TestResult {Result = "Args were " + args.Args};
    }
}

Используя netNamedPipeBinding и netTcpBinding, наше клиентское приложение будет отключено через 5 секунд, но служба будет продолжать работать неопределенно долго.

Это вызывает у меня вопрос (ы) - это ошибка? Есть ли какая-то конкретная причина, по которой WCF не захочет использовать службы с тайм-аутом, если они работают дольше, чем ожидалось?

С моей точки зрения, некоторые из возможных негативных проблем с этим включают:

  1. Лимит по умолчанию для экземпляров службы по умолчанию равен 10. Поэтому, если у вас в сервисе плохой код, который работает вечно и его 10 раз ударили, ваша служба будет полностью закрыта; новые подключения не принимаются.
  2. Нет никакого представления о том, что сервисы работают вечно - не считая пользовательских журналов или, возможно, с использованием счетчиков производительности
  3. Любые ресурсы, используемые служебным вызовом, могут храниться неопределенно долго (например, блокировки строк, страниц и таблиц SQL), если нет других механизмов для тайм-аута операции.

Ответы [ 3 ]

9 голосов
/ 12 февраля 2011

Если у вас плохой код, который работает вечно, тайм-аут может только ухудшить ситуацию. Исправьте неверный код, если это возможно! См. Статью Эрика Липперта, Осторожно с этим топором , о подобных ситуациях.

Если это в разработке, вы можете попробовать настроить System.Threading.Timer, который вызывает serviceCallThread.Abort() в вашей реализации сервиса. Тем не менее, убедитесь, что вы полностью отключили таймер, прежде чем вернуться - этот подход безумно подвержен ошибкам из-за сочетания проблем параллелизма, а не владения потоком, в который поступает вызов службы, странный поведение ThreadAbortException и проблемы, которые Эрик объясняет о слепо завершающем коде, который исчез в сорняках.

2 голосов
/ 12 февраля 2011

Я сам заметил эту проблему ... Я не могу придумать вескую причину, по которой они не будут включать тайм-ауты на стороне обслуживания как часть платформы.

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

А как же:

<system.web>
    <httpRuntime executionTimeout="inSeconds"/>
</system.web>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...