Поток прервал исключения в сервисе wcf

У меня есть служба WCF (встроенная в.NET Framework 3.5), размещенная на IIS 6.0.

Поток кода выглядит следующим образом

  1. Клиент (который является другим веб-сервисом) вызывает сервис WCF
  2. Службы WCF вызывают поток для выполнения обработки в фоновом режиме и немедленно отвечают на вызываемый объект.
  3. Фоновый поток после завершения всей обработки вызывает его обратно. Этот вызов в основном является запросом HTTP, поскольку клиент является веб-службой.

Я нагрузочно тестирую свой сервис WCF для определения пороговых значений. Наблюдение заключается в следующем:

Около 3 итераций из 1024 запросов к службе WCF в течение 1 минуты проходят успешно. Время, необходимое для завершения каждой итерации, составляет около 25-30 минут. Однако с 4-й итерации наблюдаются массовые сбои. Около 50% запросов не выполняются, за исключением следующего.

Exception-Thread был прерван.

Трассировки стека

21_10_2016_09_30_52,9:30:52 AM,Information,Thread name- apSwTTbLTETfwT3y Stack trace in ProcessTestConversion method -    at System.Threading.WaitHandle.WaitOneNative(SafeHandle waitableSafeHandle, UInt32 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
   at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext)
   at System.Threading.WaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
   at System.Net.LazyAsyncResult.WaitForCompletion(Boolean snap)
   at System.Net.Connection.SubmitRequest(HttpWebRequest request, Boolean forcedsubmit)
   at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connName)
   at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()
   .
   .(My function calls stack trace)
   .
   .

Изменения, которые я попытался решить, заключаются в следующем:

   <behavior>
    <serviceThrottling maxConcurrentCalls="2000"
                                 maxConcurrentInstances ="2400"
                                 maxConcurrentSessions ="400"/>
    </behavior>

в web.config

<system.web>
        <compilation debug="false" />
        <httpRuntime executionTimeout="1800"/>
    </system.web>

в web.config

  <system.net>
        <connectionManagement>
          <add address = "*" maxconnection = "100" />
        </connectionManagement>
      </system.net>

в web.config

ServicePointManager.DefaultConnectionLimit = 100; (Change in code)

Я установил для свойства IdleTimeout пула приложений значение 0, как предлагают многие пользователи Stackru.

Где бы ни использовались потоки, я располагаю во всех местах. Так что все потоки закрыты.

Может ли кто-нибудь сказать мне, кто прерывает потоки и почему, и существуют ли какие-либо средства или средства для отслеживания причины инициации прерывания потока?

2 ответа

Я сталкивался с этой проблемой, и это было связано с неправильным использованием класса клиента.

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

Некоторые исключения IIS не очень полезны или не соответствуют истинной причине проблемы, но чтобы понять, что было сделано для решения моей проблемы, нужно было просмотреть журналы IIS. В частности, " Правила отслеживания невыполненных запросов"

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

Я сталкивался с тем же лицом раньше. Решение состояло в том, чтобы освободить ресурсы / клиента после того, как его область была закончена путем реализации метода Dispose.

Проблема существует, так как C# using Инструкция для автоматической очистки ресурсов при использовании типизированного клиента не удалась, и любое выброшенное исключение маскируется неявным dispose, который съедает фактическое исключение и выдает другое исключение, такое как тайм-аут или другие исключения.

Оператор C# "using" приводит к вызову Dispose(). Это то же самое, что Close(), который может выдавать исключения при возникновении сетевой ошибки. Поскольку вызов Dispose () происходит неявно в закрывающей скобке блока "using", этот источник исключений, вероятно, останется незамеченным как для людей, пишущих код, так и читающих код. Это представляет потенциальный источник ошибок приложения. (из MSDN)

Вы должны освободить ресурсы, такие как:

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

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

Другим альтернативным решением может быть внедрение Dispose лайк:

/// <summary>
/// Calculator Client
/// </summary>
public partial class CalculatorClient : IDisposable
{
    #region IDisposable implementation

    /// <summary>
    /// IDisposable.Dispose implementation, calls Dispose(true).
    /// </summary>
    void IDisposable.Dispose()
    {
        Dispose(true);
    }

    /// <summary>
    /// Dispose worker method. Handles graceful shutdown of the
    /// client even if it is an faulted state.
    /// </summary>
    /// <param name="disposing">Are we disposing (alternative
    /// is to be finalizing)</param>
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            try
            {
                if (State != CommunicationState.Faulted)
                {
                    Close();
                }
            }
            finally
            {
                if (State != CommunicationState.Closed)
                {
                    Abort();
                }
            }
        }
    }

    /// <summary>
    /// Finalizer.
    /// </summary>
    CalculatorClient()
    {
        Dispose(false);
    }

    #endregion
}

Источники:

Как избежать проблем с использованием оператора MSDN

Использование и удаление клиентов WCF

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