WCF服务中的线程中止异常

18

我有一个运行在IIS 6.0上的WCF服务(使用.NET Framework 3.5构建)。

代码流程如下:

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

我正在对我的WCF服务进行负载测试以定义阈值。观察结果如下:

在1分钟内对WCF服务进行了大约3次1024个请求的迭代,全部通过。完成每次迭代所需的时间大约为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)

我已按StackOverflow上许多人的建议将App池的IdleTimeout属性设置为0。

无论何时使用流,我都在所有位置处进行了处理。因此,所有流都已关闭。

有谁能告诉我是谁在中止线程以及为什么会这样做,是否有任何工具或方法可以跟踪线程中止的原因?


客户端中止请求是否可能,因为这也会在服务器端生成异常? - Jehof
4
ASP.NET会根据需要不断启动和关闭工作进程。你的线程可能被ASP.NET关闭了。找出你的计算机可以同时运行多少个线程。在测试期间尝试跟踪处理器性能。 - Alexandr
你增加了池化调用的数量,但没有增加缓冲区大小。我有一种感觉,很多调用因此被丢弃了。 - Franck
1
哪个服务记录了错误?客户端服务还是WCF服务? - user1429080
2个回答

5
我遇到了这个问题,原因是客户端类的使用不当。当实例化一个客户端类时,它不会释放资源,从而导致吞吐量降低。会出现一个非常无用的异常"线程被中止"。通过创建一个帮助类,通用地创建一个客户端对象,然后正确实现构造函数和dispose方法来解决此问题。
有些IIS异常并不是非常有用或与实际问题的原因不符,但要找到解决我的问题的方法,就需要查看IIS日志。具体来说,是"失败请求跟踪规则"。
希望这能帮到你,我理解你的沮丧,这真是一件头痛的事情。

2

我之前也遇到过同样的问题。解决方法是在范围结束后实现Dispose方法以释放资源/客户端。

问题存在于C# using语句自动清理使用类型化客户端时的资源不成功,任何抛出的异常都被隐式dispose掉,并且会抛出一些其他异常,如超时或其他异常。

C# "using"语句会导致调用Dispose()。这与Close()相同,当网络错误发生时可能会抛出异常。由于在“using”块的结束括号处隐式调用Dispose(),因此人们编写和阅读代码时很容易忽略此类异常。这代表了潜在的应用程序错误来源。(来自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客户端


1
抱歉回复晚了。非常感谢你们的时间。由于我希望问题能尽快得到解决,一个解决方法是增加机器的内存大小,这解决了问题。 - shivkumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接