C# wcf服务中的线程中止异常

C# wcf服务中的线程中止异常,c#,wcf,threadabortexception,thread-abort,C#,Wcf,Threadabortexception,Thread Abort,我有一个WCF服务(内置于.NET framework 3.5中)托管在IIS 6.0上 代码流程如下所示 客户端(另一个web服务)调用WCF服务 WCF服务在后台调用线程进行处理,并立即响应被调用方 后台线程完成所有处理后,将回调线程。这个调用基本上是一个HTTPs请求,因为客户端是一个web服务 我正在对WCF服务进行负载测试,以定义阈值。观察结果如下: <behavior> <serviceThrottling maxConcurrentCalls="20

我有一个WCF服务(内置于.NET framework 3.5中)托管在IIS 6.0上

代码流程如下所示

  • 客户端(另一个web服务)调用WCF服务
  • WCF服务在后台调用线程进行处理,并立即响应被调用方
  • 后台线程完成所有处理后,将回调线程。这个调用基本上是一个HTTPs请求,因为客户端是一个web服务
  • 我正在对WCF服务进行负载测试,以定义阈值。观察结果如下:

       <behavior>
        <serviceThrottling maxConcurrentCalls="2000"
                                     maxConcurrentInstances ="2400"
                                     maxConcurrentSessions ="400"/>
        </behavior>
    
    在1分钟内对WCF服务发出的1024个请求中,大约3次迭代成功通过。完成每个迭代所需的时间约为25-30分钟。 然而,从第4次迭代中可以看到批量故障。大约50%的请求失败,但有以下例外

    异常线程正在中止

    堆栈跟踪

    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>
    
    我已经按照StackOverflow上许多人的建议,将应用程序池的IdleTimeout属性设置为0

    无论在哪里使用溪流,我都会在所有地方进行处理。所以所有的溪流都关闭了


    有人能告诉我谁正在中止线程,为什么要中止线程,以及有什么方法或工具可以追踪线程中止启动的原因吗?

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

    发生的情况是,当客户机类被实例化时,它不会释放回资源,从而导致吞吐量降低。将发生一个非常无用的异常“线程正在中止”。通过创建一个helper类来解决这个问题,该类generically创建了一个客户机对象,然后正确地实现了构造函数和dispose方法

    一些IIS异常对问题的实际原因不是很有帮助,也不是真的,但要弄清解决问题的方法,请查看IIS日志。特别是“


    希望这会有所帮助,我能理解你的沮丧,这是一个令人头痛的问题。

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

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

    C#“using”语句导致调用Dispose()。这与Close()相同,它可能在发生网络错误时引发异常。由于对Dispose()的调用隐式地发生在“using”块的右大括号处,因此编写代码和阅读代码的人可能都不会注意到这一异常源。这是应用程序错误的潜在来源。(来自)

    您应该释放以下资源:

    try
    {
        ...
        client.Close();
    }
    catch (CommunicationException e)
    {
        ...
        client.Abort();
    }
    catch (TimeoutException e)
    {
        ...
        client.Abort();
    }
    catch (Exception e)
    {
        ...
        client.Abort();
        throw;
    }
    
    通过这种方式,您不仅可以找到异常的实际来源,还可以在出现某些执行选项时释放资源

    其他备选方案可以实施
    处置
    如下:

    /// <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
    }
    
    //
    ///计算器客户端
    /// 
    公共部分类计算器客户端:IDisposable
    {
    #区域IDisposable实现
    /// 
    ///IDisposable.Dispose实现,调用Dispose(true)。
    /// 
    void IDisposable.Dispose()无效
    {
    处置(真实);
    }
    /// 
    ///Dispose worker方法。处理的正常关闭
    ///客户端,即使它处于故障状态。
    /// 
    ///我们正在处理(替代方案)吗
    ///(正在定稿)
    受保护的虚拟void Dispose(bool disposing)
    {
    如果(处置)
    {
    尝试
    {
    如果(状态!=通信状态出错)
    {
    Close();
    }
    }
    最后
    {
    如果(状态!=通信状态.关闭)
    {
    中止();
    }
    }
    }
    }
    /// 
    ///终结器。
    /// 
    计算器客户端()
    {
    处置(虚假);
    }
    #端区
    }
    
    来源

    MSDN


    客户端是否可能中止请求,因为这也会在服务器端生成异常ASP.NET会根据需要随时生成和终止工作进程。您的线程可能正被ASP.NET关闭。了解您的计算机上可以同时运行多少线程。在测试过程中,还要尝试跟踪处理器性能。您增加了池调用的数量,但没有增加缓冲区大小。我感觉有很多电话因此而被中断。哪个服务记录了错误?客户端服务还是WCF服务?很抱歉延迟回复。非常感谢你们抽出时间,伙计们。由于我希望问题尽快得到解决,一个解决办法是增加解决问题的机器的内存大小。
    try
    {
        ...
        client.Close();
    }
    catch (CommunicationException e)
    {
        ...
        client.Abort();
    }
    catch (TimeoutException e)
    {
        ...
        client.Abort();
    }
    catch (Exception e)
    {
        ...
        client.Abort();
        throw;
    }
    
    /// <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
    }