我有一个托管在IIS 6.0上的WCF服务(内置于.NET framework 3.5).
代码流程如下
我正在加载测试我的WCF服务以定义阈值.观察结果如下:
在1分钟内对WCF服务进行的大约3次迭代的1024次请求成功通过.完成每次迭代所需的时间约为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)
.
.
Run Code Online (Sandbox Code Playgroud)
我试图解决这些问题的变化如下:
<behavior>
<serviceThrottling maxConcurrentCalls="2000" …Run Code Online (Sandbox Code Playgroud) 我在C#中使用了一个线程,我将IsBackground属性设置为true.线程在循环中运行一些代码,直到应用程序关闭.当应用程序关闭时,线程也会停止执行(因为我设置了IsBackground = true).
应用程序如何杀死线程?它似乎不是通过调用abort来实现的,因为我没有得到ThreadAbortException.它是在幕后发生的吗?我想在我的循环块中做一些回滚.
我知道我可以自己在线程上调用abort,但我想知道应用程序如何关闭我的后台线程,以及我是否可以从线程内部做出反应.我知道我可以订阅Application.ApplicationExit事件,但是我在服务和winform中运行这个代码,我更喜欢在循环中捕获异常,所以我能够在finally语句中回滚.
请不要在此qustion上设置重复标志 - 它不是"为什么发生ThreadAbortException",它是关于"为什么w3wp.exe进程在ThreadAbortException之后终止".
假设我们有简单的Web应用程序,其代码示例如下:
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("http://google.com");
}
Run Code Online (Sandbox Code Playgroud)
事实上这意味着什么(参见Response.End()被认为是有害的?):
protected void Page_Load(object sender, EventArgs e)
{
...response write some data...
System.Threading.Thread.CurrentThread.Abort();
}
Run Code Online (Sandbox Code Playgroud)
在我的计算机(Windows 10 Pro + IIS)上,此代码导致IIS池进程终止,错误代码为0x0(重定向不执行).在其他计算机(不是Windows 10)上,此代码仅生成ThreadAborted异常,但进程继续工作(重定向执行).
有人可以检查这个样本并解释发生了什么吗?
更新 这里有一些与此问题相关的Windows事件日志.
记录#1
发生未处理的异常,并终止该过程.
应用ID:/ LM/W3SVC/1/ROOT/AS
进程ID:6700
例外:System.Threading.ThreadAbortException
消息:线程正在中止.
StackTrace:位于System.Web.Hosting.PipelineRuntime.ProcessRequestNotification的System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32标志)的System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr,HttpContext context) (IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32 flags)
记录#2
Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad
Faulting module name: KERNELBASE.dll, version: 10.0.10240.16384, time stamp: 0x559f3b2a
Exception code: 0xe0434352
Fault …Run Code Online (Sandbox Code Playgroud) 我从"Windows上的并发编程"一书中获得了以下代码:
void Main()
{
try
{
try
{
Console.WriteLine("Inside Main Method");
Thread.CurrentThread.Abort();
}
catch(ThreadAbortException)
{
Console.WriteLine("Inside First Catch");
// Trying to swallow but CLR throws it again....
}
}
catch(ThreadAbortException)
{
Console.WriteLine("Inside Second Catch");
//Thread.ResetAbort();
}
}
Run Code Online (Sandbox Code Playgroud)
我有兴趣知道为什么CLR会重新抛出ThreadAbortException?它一直这样做,直到我调用"Thread.ResetAbort()".其次,还有其他系统定义的异常,它会从CLR获得特殊处理吗?
我试图使用ExportToHttpResponse如下导出Crystal ReportDocument :
report.ExportToHttpResponse(exportOptions, HttpContext.Current.Response, true, "test");
Run Code Online (Sandbox Code Playgroud)
当我第一次尝试运行时,我收到了一个System.Threading.ThreadAbortException.阅读有关如何,这是一个已知的误差后ExportToHttpResponse在这个问题,我想实现像这样一个try/catch块包裹语句的建议的解决方法:
try
{
report.ExportToHttpResponse(expOptions, HttpContext.Current.Response, true, "test");
}
catch (System.Threading.ThreadAbortException e)
{
}
Run Code Online (Sandbox Code Playgroud)
据我了解,这应该捕获并忽略错误,然后继续.但是,我仍然得到System.Threading.ThreadAbortException了catch语句的结束括号.我的问题是为什么即使我显然正在捕获它仍然会收到异常,我怎么能去修复它以便忽略异常?
我有一个System.Timers.Timer定时器,它AutoReset被设置为false.我使用a try/finally来确保Start它的结束时callback的计时器(我使用计时器这种方式来防止重复callback执行).码:
// inside timer call back
try
{
// Do something
}
finally
{
timer.Start(); // Is this line always executed?
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如果执行线程是什么会发生什么Aborted?该finally部分是否仍然执行或者没有线程来运行该部分?
今晚我与约束执行区一起玩耍,以更好地完善我对更好细节的理解。我以前曾经使用过它们,但是在那种情况下,我主要严格遵守既定模式。无论如何,我注意到了一些我无法完全解释的奇特之处。
考虑下面的代码。注意,我的目标是.NET 4.5,并在没有附加调试器的情况下使用Release版本对其进行了测试。
public class Program
{
public static void Main(string[] args)
{
bool toggle = false;
bool didfinally = false;
var thread = new Thread(
() =>
{
Console.WriteLine("running");
RuntimeHelpers.PrepareConstrainedRegions();
try
{
while (true)
{
toggle = !toggle;
}
}
finally
{
didfinally = true;
}
});
thread.Start();
Console.WriteLine("sleeping");
Thread.Sleep(1000);
Console.WriteLine("aborting");
thread.Abort();
Console.WriteLine("aborted");
thread.Join();
Console.WriteLine("joined");
Console.WriteLine("didfinally=" + didfinally);
Console.Read();
}
}
Run Code Online (Sandbox Code Playgroud)
您认为该程序的输出是什么?
在猜测之前,请阅读文档。我在下面包括相关部分。
约束执行区(CER)是创作可靠的托管代码的机制的一部分。CER定义了一个区域,在该区域中,公共语言运行库(CLR)受到约束,无法抛出带外异常,这将阻止该区域中的代码整体执行。在该区域内,用户代码无法执行代码,从而导致抛出带外异常。PrepareConstrainedRegions方法必须立即在try块之前,并将catch块,fault块和Fault块标记为受约束的执行区域。一旦标记为受约束区域,代码就只能调用具有强可靠性合同的其他代码,并且除非代码准备好处理失败,否则代码不应分配或对未准备好的方法或不可靠的方法进行虚拟调用。对于在CER中执行的代码,CLR延迟线程中止。
和
可靠性try / catch / finally是一种异常处理机制,具有与非托管版本相同的可预测性保证。 …
我收到以下异常:
Exception of type ThreadAbortException occurred: System.Threading.ThreadAbortException: ThreadAbortException
at System.Threading.EventWaitHandle.WaitOne(Int32 millisecondsTimeout, Boolean exitContext)
at MyCode.ProcessEvents()
Run Code Online (Sandbox Code Playgroud)
我对它如何发生感到困惑。尽管我的代码可能会中止另一个线程(包括设置WaitHandle的线程),但我确定我不会中止该特定线程。这使我相信该框架正在引发异常,或者某个线程的线程异常接收正在以某种方式渗入该线程。我认为这两者都是不可能的。
因此,如果我没有在此线程上调用Thread.Abort(),它将如何最终导致ThreadAbortException?
我想检查以下代码是否能够抵抗 ThreadAbortException 并且不会导致孤儿锁。如果不是,那么避免孤儿锁的最佳模式是什么?
ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public void DoStaff()
{
_lock.EnterWriteLock();
//Is this place where ThreadAbotException can corrupt my code, or is there JIT optimalization which prevent this from happening???
try
{
...
}
finally
{
_lock.ExitWriteLock();
}
}
Run Code Online (Sandbox Code Playgroud)
根据以下链接http://chabster.blogspot.cz/2013/07/a-story-of-orphaned-readerwriterlockslim.html,有(或至少有)可能的方法如何创建孤儿锁,但我正在运行示例编码了一段时间,没有任何运气。
我正在使用.NET 4.0
调试和发布中的行为有什么区别吗?
我正在使用 .NET 1.1 兼容模式进行未处理的异常处理。问题是,当 LegacyUnhandledExceptionPolicy 设置为“1”(这是我想要的)时,我无法捕获并吞下 ThreadAbortException。
示例代码:
应用程序配置:
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
代码:
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += _onBackgroundThreadCrash;
var t = new Thread(_worker) { IsBackground = true };
t.Start();
Thread.Sleep(1000);
t.Abort();
Console.ReadLine();
}
private static void _worker() {
try {
while (true);
} catch (ThreadAbortException) {
// expected thread exit, don't rethrow
}
}
private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
Console.WriteLine(e.ExceptionObject as Exception);
}
}
Run Code Online (Sandbox Code Playgroud)
当遗留异常处理为“0”(OFF)时,上面的代码会如预期的那样安静地吞下 ThreadAbortException。
但是,当遗留异常处理为“1”时,上面的代码将 ThreadAbortException …
c# ×9
.net ×3
.net-4.6 ×1
asp.net ×1
cer ×1
clr ×1
iis ×1
isbackground ×1
thread-abort ×1
timer ×1
try-catch ×1
wcf ×1
windows-10 ×1