线程中止wcf服务中的异常如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (20)

我有一个在IIS 6.0上托管的WCF服务(内置.NET Framework 3.5)。

代码的流程如下

  1. 客户端(这是另一个Web服务)调用WCF服务
  2. WCF服务调用一个线程在后台执行处理并立即响应被调用者。
  3. 后台线程完成所有处理后,回调线程。这个调用基本上是一个HTTPs请求,因为客户端是一个Web服务。

我负载测试我的WCF服务来定义阈值。观察结果如下:

在1分钟内向WCF服务发送的约1024次请求约3次迭代成功。完成每次迭代所需的时间约为25-30分钟。但是从第4次迭代中可以看到大量失败。大约50%的请求失败,但有以下异常。

Exception-Thread was being aborted.

堆栈跟踪

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)

将App池的IdleTimeout属性设置为0。

任何人都可以告诉我谁在中止线程,为什么还有任何方法或工具来追踪线程中止启动的原因?

提问于
用户回答回答于

我以前也有过同样的表情。解决方案是在资源/客户端的范围结束后,通过实现处置方法。

问题存在于C#之后using语句在使用类型化客户端时自动清理资源是不成功的,任何抛出的异常都会被隐式Dispose掩盖,这会导致实际的异常&抛出一些其他异常,比如超时或其他异常。

C#“使用”语句将导致调用dist()。这与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客户端的使用和处理

用户回答回答于

我遇到了这个问题,这是由于不恰当地使用客户端类。

发生什么事情是,当一个客户类被实例化时,它不会释放资源导致吞吐量下降。一个非常无益的例外“线程被中止”会发生。这是通过创建一个通用盟友创建一个客户端对象,然后实现构造函数并正确配置方法的帮助类来解决的。

一些IIS异常对问题的实际原因不是非常有帮助或不正确,但要解决我的问题的底部是查看IIS日志。特别是“ 失败的请求追踪规则

希望这会有所帮助,我可以理解你的挫败感,这是一个令人头痛的问题。

扫码关注云+社区