Сервис удаленного взаимодействия.NET, по-видимому, дает сбой и перестает отвечать на запросы клиентов.

У меня есть служба удаленного взаимодействия.NET, которая работает нормально большую часть времени. Если происходит исключение или ошибка, она записывает ошибку в файл, но продолжает работать.

Однако примерно раз в две недели служба перестает отвечать на запросы клиентов, что приводит к сбою клиентского приложения с SocketException со следующим сообщением:

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Никаких исключений или трассировки стека не записывается в наш файл журнала, поэтому я не могу понять, где происходит сбой службы, из-за чего я полагаю, что она находится где-то за пределами моего кода, который дает сбой. Какие дополнительные шаги я могу предпринять, чтобы выяснить причину этого сбоя? Я мог бы предположить, что он что-то записывает в EventLog где-то, но я не очень хорошо знаком с системой регистрации событий Windows, поэтому я не совсем уверен, где искать.

Заранее спасибо за любую помощь с этим.

РЕДАКТИРОВАТЬ: Забыл упомянуть, остановка или перезапуск службы ничего не делает, служба никогда не отвечает. Мне нужно вручную завершить процесс, прежде чем я смогу снова запустить службу.

РЕДАКТИРОВАТЬ 2:

public class ClientInfoServerSinkProvider :
       IServerChannelSinkProvider
   {
      private IServerChannelSinkProvider _nextProvider = null;

      public ClientInfoServerSinkProvider()
      {
      }

      public ClientInfoServerSinkProvider(
              IDictionary properties,
              ICollection providerData)
      {
      }

      public IServerChannelSinkProvider Next
      {
         get { return _nextProvider; }
         set { _nextProvider = value; }
      }

      public IServerChannelSink CreateSink(IChannelReceiver channel)
      {
         IServerChannelSink nextSink = null;

         if (_nextProvider != null)
         {
            nextSink = _nextProvider.CreateSink(channel);
         }
         return new ClientIPServerSink(nextSink);
      }

      public void GetChannelData(IChannelDataStore channelData)
      {
      }
   }

   public class ClientIPServerSink :
       BaseChannelObjectWithProperties,
       IServerChannelSink,
       IChannelSinkBase
   {

      private IServerChannelSink _nextSink;

      public ClientIPServerSink(IServerChannelSink next)
      {
         _nextSink = next;
      }

      public IServerChannelSink NextChannelSink
      {
         get { return _nextSink; }
         set { _nextSink = value; }
      }

      public void AsyncProcessResponse(
              IServerResponseChannelSinkStack sinkStack,
              Object state,
              IMessage message,
              ITransportHeaders headers,
              Stream stream)
      {
         IPAddress ip = headers[CommonTransportKeys.IPAddress] as IPAddress;
         CallContext.SetData("ClientIPAddress", ip);
         sinkStack.AsyncProcessResponse(message, headers, stream);
      }

      public Stream GetResponseStream(
              IServerResponseChannelSinkStack sinkStack,
              Object state,
              IMessage message,
              ITransportHeaders headers)
      {
         return null;
      }

      public ServerProcessing ProcessMessage(
              IServerChannelSinkStack sinkStack,
              IMessage requestMsg,
              ITransportHeaders requestHeaders,
              Stream requestStream,
              out IMessage responseMsg,
              out ITransportHeaders responseHeaders,
              out Stream responseStream)
      {
         if (_nextSink != null)
         {
            IPAddress ip =
                    requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;

            CallContext.SetData("ClientIPAddress", ip);
            ServerProcessing spres = _nextSink.ProcessMessage(
                    sinkStack,
                    requestMsg,
                    requestHeaders,
                    requestStream,
                    out responseMsg,
                    out responseHeaders,
                    out responseStream);
            return spres;
         }
         else
         {
            responseMsg = null;
            responseHeaders = null;
            responseStream = null;
            return new ServerProcessing();
         }
      }

2 ответа

Решение

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

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

Это не может быть лучше, пока вы не используете этот телефон, чтобы поговорить с сервисным программистом и вовлечь его в проблему. Кто-то должен будет отладить это. И да, это будет трудно, отказ один раз в две недели не может считаться достаточно критичным. Или слишком долго сидеть без дела, ожидая этого. Единственная практическая вещь, которую вы можете сделать, чтобы помочь - это создать мини-дамп процесса и передать его сервисному программисту, чтобы он мог что-то подсунуть. Если служба работает на другом компьютере, подключите администратора локальной сети.

Другие вопросы по тегам