当一个System.Web.HttpResponse.End()被调用时,System.Thread.Abort被触发,我猜是(或触发)异常?我有一些日志记录,这是在日志文件中列出的...
第一次机会
exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll
12/14/2008 01:09:31::
Error in Path :/authenticate
Raw Url :/authenticate
Message :Thread was being aborted.
Source :mscorlib
Stack Trace : at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at DotNetOpenId.Response.Send()
at DotNetOpenId.RelyingParty.AuthenticationRequest.RedirectToProvider()
at MyProject.Services.Authentication.OpenIdAuthenticationService.GetOpenIdPersonaDetails(Uri serviceUri) in C:\Users\Pure Krome\Documents\Visual Studio 2008\Projects\MyProject\Projects\Services\Authentication\OpenIdAuthenticationService.cs:line 108
at MyProject.Mvc.Controllers.AuthenticationController.Authenticate() in C:\Users\Pure Krome\Documents\Visual Studio 2008\Projects\MyProject\Projects\MVC Application\Controllers\AuthenticationController.cs:line 69
TargetSite :Void AbortInternal()
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in Ackbar.Mvc.DLL
An exception of type 'System.Threading.ThreadAbortException' occurred in Ackbar.Mvc.DLL but was …
Run Code Online (Sandbox Code Playgroud) 当无效输入传递给方法或对象即将进入无效状态时,我们通常抛出异常.让我们考虑以下示例
private void SomeMethod(string value)
{
if(value == null)
throw new ArgumentNullException("value");
//Method logic goes here
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我插入了抛出的throw语句ArgumentNullException
.我的问题是运行时如何设法抛出ThreadAbortException
.显然,throw
在所有方法中都不可能使用语句,即使运行时也设法引入ThreadAbortException
我们的自定义方法.
我想知道他们是怎么做到的?我很想知道幕后发生了什么,我打开了一个反射器打开Thread.Abort
并结束了这个
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();//Implemented in CLR
Run Code Online (Sandbox Code Playgroud)
然后我用Google搜索并发现这个ThreadAbortException如何真正起作用.这个链接说运行时通过QueueUserAPC
函数发布APC ,这就是他们如何做到这一点.我不知道QueueUserAPC
方法我只是试着看一下代码是否可行.以下代码显示了我的尝试.
[DllImport("kernel32.dll")]
static extern uint QueueUserAPC(ApcDelegate pfnAPC, IntPtr hThread, UIntPtr dwData);
delegate void ApcDelegate(UIntPtr dwParam);
Thread t = new Thread(Threadproc);
t.Start();
//wait for thread to start
uint result = QueueUserAPC(APC, new IntPtr(nativeId), (UIntPtr)0);//returns zero(fails)
int error = …
Run Code Online (Sandbox Code Playgroud) 我有一个托管在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) 我觉得这种行为不应该发生.这是场景:
启动一个长期运行的SQL事务.
运行sql命令的线程被中止(不是我们的代码!)
当线程返回托管代码时,SqlConnection的状态为"已关闭" - 但该事务仍在sql server上打开.
SQLConnection可以重新打开,你可以尝试在事务上调用回滚,但它没有效果(不是我期望这种行为.重点是没有办法访问数据库上的事务并滚动它背部.)
问题只是在线程中止时没有正确清理事务.这是.Net 1.1,2.0和2.0 SP1的问题.我们正在运行.Net 3.5 SP1.
这是一个说明问题的示例程序.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Threading;
namespace ConsoleApplication1
{
class Run
{
static Thread transactionThread;
public class ConnectionHolder : IDisposable
{
public void Dispose()
{
}
public void executeLongTransaction()
{
Console.WriteLine("Starting a long running transaction.");
using (SqlConnection _con = new SqlConnection("Data Source=<YourServer>;Initial Catalog=<YourDB>;Integrated Security=True;Persist Security Info=False;Max Pool Size=200;MultipleActiveResultSets=True;Connect Timeout=30;Application Name=ConsoleApplication1.vshost"))
{
try
{
SqlTransaction trans = null;
trans = _con.BeginTransaction(); …
Run Code Online (Sandbox Code Playgroud) 我是一名Java程序员,他被要求对C#应用程序进行一些更改.我已经和C#一起工作了一个星期了,而且我终于找到了一个观察文档没有帮助的地方,当我谷歌时我找不到解决方案.
在这种情况下,我有一个Windows服务来处理到达MSMQ的消息.当收到一条消息时,当前正在侦听的线程将其拾取并开始执行需要几秒钟的操作.
public void Start()
{
this.listen = true;
for (int i = 0; i < Constants.ThreadMaxCount; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartListening), i);
}
...
private void StartListening(Object threadContext)
{
int threadId = (int)threadContext;
threads[threadId] = Thread.CurrentThread;
PostRequest postReq;
while(this.listen)
{
System.Threading.Monitor.Enter(locker);
try
{
postReq = GettingAMessage();
}
finally
{
System.Threading.Monitor.Exit(locker);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
GettingAMessage()具有以下监听消息的行:
Task<Message> ts = Task.Factory.FromAsync<Message>
(queue.BeginReceive(), queue.EndReceive);
ts.Wait();
Run Code Online (Sandbox Code Playgroud)
问题是,当调用Stop()方法并且没有消息进入MSMQ时,线程都坐在那里等待消息.我尝试过使用超时,但这种方法对我来说似乎并不优雅(并且切换到了Task Factory,我不知道如何实现它们).我的解决方案是将每个线程的引用添加到数组中,以便我可以取消它们.创建后,每个工作线程调用以下内容.
threads[threadId] = Thread.CurrentThread;
Run Code Online (Sandbox Code Playgroud)
然后应该被中止
public void Stop()
{
try
{
this.listen = false;
foreach(Thread a in …
Run Code Online (Sandbox Code Playgroud) 我真的很感激任何建议,无论多么简单或复杂,帮助我解决这个问题.
我有一些生成小报告文件的代码.对于集合中的每个文件,执行存储过程以通过XML阅读器获取数据(它是一个非常大的结果集).当我创造了这一切,并逐步完成它,一切都很好.生成文件,没有错误.
该库通过远程处理调用,并通过IIS托管.当我部署已编译的库并调用它时,它能够生成一些报告,但随后会抛出一个Thread Abort Exception.如果我将调试器附加到asp工作进程,并逐步执行代码,我没有问题.
看到这种失败是非常一致的,我寻找相似之处并发现失败发生在不同的报告上,但似乎发生在大约相同的时间点.
这让我认为这是一个超时设置,调试器重写,我做了一些粗略的整个过程时间(不是单一的失败代码),它似乎在大约200秒后失败.web.config executionTimeout设置为600分钟(足够高).此服务器应用程序还有其他部分需要COM +事务(2分钟超时),但这不是其中之一.我不知道它可能达到的超时时间(大约200秒大关).
SQL Connection超时默认保留(连接成功打开),命令超时为300秒(执行命令只需12-15).
我运行了SQL分析器,它显示结果正确返回(所有语句和RPC完成 - 没有错误).通过SSMS执行代码可提供完美的结果.
使用反射器,我钻进了SNINativeMethodWrapper,它是非托管代码的包装器,我无法看到它试图实际做什么.我只能假设(可能错误地)代码已经从SQL服务器接收到TDS,并且包装器试图获得与数据包关联的连接,但它不能.
我尝试使用不同的方法(ExecScalar,DataAdapter),但它们都在内部使用ExecuteReader.
我尝试禁用连接池并强制客户端使用与服务器相同的数据包大小.
Private Function GetDataAsXmlDoc(ByVal cmd As SqlClient.SqlCommand) As XmlDocument
Dim _xmlDoc As XmlDocument
Using _connection As New SqlClient.SqlConnection(GetConnectionString())
Logging.DebugEvent.Raise(Me.GetType.Namespace, Reflection.MethodBase.GetCurrentMethod().Name, _
"No cached data found or used. Getting data for report from the database using SQL connection.")
Dim _xmlReader As XmlReader
'DataAdapter,ExecuteScalar, ExecuteXmlReader all use ExecuteReader internally and suffer the same problem.'
'If you dont believe me, reflect it …
Run Code Online (Sandbox Code Playgroud) 我的程序加载时,我在后台线程上显示启动画面.加载后我将中止Thread,因为它的唯一目的是显示一个Now Loading飞溅表单.
我的问题是,当中止一个Thread时,它会抛出一个ThreadAbortException
用户只需单击Continue on.
我该如何处理?我试图压制它 - >
try
{
Program.splashThread.Abort();
}
catch(Exception ex)
{
}
Run Code Online (Sandbox Code Playgroud)
但我有一种感觉,这会让我在这里大吼大叫,它无论如何都行不通.
谢谢!
在此代码中,button1
单击两次时,它将创建2个单独的线程.只需单击一下,它就会在堆上创建一个新线程,而field将t1
指向堆上的新线程.当我单击时button2
,它将中止最后一个线程(t1
指的是).
我如何中止其他线程?
Thread t1;
ThreadStart ts1;
private void button1_Click(object sender, EventArgs e)
{
ts1 = new ThreadStart(myfunc);
t1 = new Thread(ts1);
t1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
t1.Abort();
}
Run Code Online (Sandbox Code Playgroud) 以下代码的缺点是,在主线程重置waithandle之后,工作线程既不会立即终止也不会执行最终操作.相反,它将继续执行它正在进行的操作,直到它到达循环的下一次迭代,此时它将无限期地被阻塞.
static void Main()
{
ManualResetEvent m = new ManualResetEvent(true); // or bool b = true
Thread thread = new Thread(new ThreadStart(delegate()
{
while(m.WaitOne()) //or while(b)
{
//do something
}
//perform final operation and exit
}));
thread.Start();
//do something
m.Reset(); //or b = false
//do something else
}
Run Code Online (Sandbox Code Playgroud)
下面的代码有一个缺点,它使用Abort()方法(有人说它应该不惜一切代价避免),但完全正是我正在寻找的:强制工作线程突破循环主线程告诉它这样做,执行最后一个操作,然后退出.
static void Main()
{
Thread thread = new Thread(new ThreadStart(delegate()
{
try
{
while(true)
{
//do something
}
}
catch(ThreadAbortException e)
{
//perform final operation and exit
}
}));
thread.Start();
//do …
Run Code Online (Sandbox Code Playgroud) 我创建了一个线程A,并决定从线程A内部中止它.这可能吗?如果是这样我怎么能这样做?
谢谢您的帮助!
thread-abort ×10
c# ×8
.net ×4
ado.net ×1
asp.net ×1
httpresponse ×1
iis-6 ×1
msmq ×1
sql-server ×1
vb.net ×1
wcf ×1
winforms ×1