在 ASP.NET Web 表单中按钮的 OnClick 方法中,我调用了 Response.Redirect(),这会导致系统中止线程并显示错误消息:
Exception thrown: 'System.Threading.ThreadAbortException' in mscorlib.dll
Run Code Online (Sandbox Code Playgroud)
这里有一些与此类似的问题,使用我更改的解决方案:
Response.Redirect("~/UI/Home.aspx");
Run Code Online (Sandbox Code Playgroud)
到
Response.Redirect("~/UI/Home.aspx", false);
Context.ApplicationInstance.CompleteRequest();
Run Code Online (Sandbox Code Playgroud)
但是我仍然遇到同样的问题。我使用调试器运行了代码,一切都成功执行,直到我调用 Response.Redirect();。
点击函数
protected void btnLogin_Click(object sender, EventArgs e)
{
SiteUser s = null;
try
{
string email = txtEmail.Text;
string pwd = txtPwd.Text;
s = DBConnection.login(email, pwd);
}
catch (Exception ex)
{
Console.Write(ex);
lblLoginError.Text = "Error logging in.";
}
if (s != null)
{
Session["UserSession"] = s;
Response.Redirect("~/UI/Home.aspx", false);
Context.ApplicationInstance.CompleteRequest();
}
else
{
lblLoginError.Text = "User not found. Please check your …Run Code Online (Sandbox Code Playgroud) 我有一些遗留代码,我想要进行测试.这是必需品的复制品:
public class LegacyUnit
{
private readonly ICollaborator collaborator;
public LegacyUnit(ICollaborator collaborator)
{
this.collaborator = collaborator;
}
public object GetStuff(HttpContextBase context, string input)
{
try
{
if (input == "")
{
context.Response.End();
}
collaborator.DoOtherStuff();
return "Done!";
}
catch (ThreadAbortException)
{ }
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这个遗留单元存在一些问题,但是现在我只是试图让它受到考验.具体来说,我想测试,如果提出a ,collaborator.DoOtherStuff则不会调用.Response.End()ThreadAbort
问题:你如何提出这样的例外?
我已经阅读了这个问题及其答案ThreadAbortException,并了解它的特殊之处.但是,我从这些帖子中看不到如何在单元测试中处理这个问题.
这是我的尝试:
[Test]
public void DoesNotCallCollaboratorOnThreadAbort()
{
var testResponseMock = new Mock<HttpResponseBase>();
var testContextMock = new Mock<HttpContextBase>();
var collaboratorMock = new Mock<ICollaborator>();
testContextMock.Setup(x …Run Code Online (Sandbox Code Playgroud) 根据MSDN,AppDomain.Unload导致卸载AppDomain中的所有线程抛出线程中止异常.
域中的线程使用Abort方法终止,该方法在线程中抛出ThreadAbortException.虽然线程应该立即终止,但它可以在finally子句中继续执行不可预测的时间量.- 来自MSDN
所以我的理解是每次我在任何预期在这个AppDomain中运行的代码编写代码时,我都不得不期望任何线程都可以随时发生线程中止.这是真的?所有代码都应该假设可以随时抛出ThreadAbortException吗?
实际上这实际上是elimates catch(Exception ex),因为它会捕获ThreadAbortException并尝试处理它,通常是通过记录一个真的不应该记录的错误(因为卸载AppDomain实际上不是一个例外).
是否还需要考虑其他因素以避免不必要的异常处理/错误记录?
我有一个分析大型XML文件并基于该内容构建WPF UI控件的应用程序。此任务通常需要大约15-30秒。为了通知用户正在运行的任务,我显示了一个简单的中间进度对话框窗口,例如:
Thread progressDialogThread = new Thread(() =>
{
Window window = new Window
{
Content = new ProgressDialog(),
Height = 100,
Width = 150,
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen
};
window.ShowDialog();
});
progressDialogThread.SetApartmentState(ApartmentState.STA);
progressDialogThread.IsBackground = true;
progressDialogThread.Start();
buildUI();
progressDialogThread.Abort();
Run Code Online (Sandbox Code Playgroud)
这是可行的,但是progressDialogThread.Start()当应该再次解析XML时,有时会在上获得ThreadAbortException 。
有谁知道“关闭”进度对话框的更好方法?
由于控件必须构建在主UI线程上,因此我不能使用backgroundworker ...
XAML中的进度对话框本身如下所示:
<UserControl x:Class="MyDialog.ProgressDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyDialog"
mc:Ignorable="d"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Height="100" Width="150">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Label HorizontalAlignment="Center">Please wait</Label>
<ProgressBar
Style="{StaticResource MaterialDesignCircularProgressBar}"
Value="0"
IsIndeterminate="True" Width="40" Height="41" Margin="55,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</UserControl>
Run Code Online (Sandbox Code Playgroud) 如果它需要太多时间我必须Timer取消Thread它.
System.Timers.Timer timer_timers = new System.Timers.Timer();
Thread thread = new Thread(startJob);
thread.Name = "VICTIM_THREAD";
Run Code Online (Sandbox Code Playgroud)
在启动Thread方法时,我启动Timer并将当前Thread作为参数传递给事件.
public void startJob()
{
Debug.WriteLine("Name: " + Thread.CurrentThread.Name);
timer_timers.Elapsed += (sender, e) => T_Elapsed(sender, e, Thread.CurrentThread);
timer_timers.Interval = 5000;
// Start simulation process
while (true)
{
Thread.Sleep(700);
Debug.WriteLine("Thread: " + Thread.CurrentThread.Name + " ALIVE: " + thread.IsAlive);
}
}
Run Code Online (Sandbox Code Playgroud)
定时器事件:
private void T_Elapsed(object sender, ElapsedEventArgs e, Thread currentThread)
{
// EDIT: show the correct NAME! of the …Run Code Online (Sandbox Code Playgroud) c# ×5
.net ×2
appdomain ×1
asp.net ×1
exception ×1
moq ×1
mscorlib ×1
thread-abort ×1
timer ×1
unit-testing ×1