前几天在博问中看到一个问题——Response.End()后,是否停止执行?MVC与WebForm不一致。看到LZ的描述后,虽然奇怪于为何用Response.End()而不用return方式去控制流程,但基于自己以往的认识,还是回答了说需要return。

因为以往的开发过程中,虽然没有用过Response.End()的方式像LZ所说地那样“方便地从多层调用中退出”,但是始终是认为Response.End()是不能终止其后代码执行的,思维路线大概是:Response.End()只是结束了HTTP返回流的写入,但是代码依然没有return啊,例如Page_Load中使用了Response.End(),但是这个方法并没有被跳出/终止。

之后LZ编辑了问题,继续提到了问题没有解决,又附带了伪代码希望大家帮忙改进书写方式。直到此时,由于自己的思维惯性,我依然我没有去写DEMO去验证对比webform和mvc下的Response.End(),简单地用主动throw new Exception的方式写出了MVC下“好看一点”的代码。

之后在回复中,LZ再次重复了Response.End()确实在webform和mvc中存在差异,我抱着试一试地心态测了一个疗程。真的有点吃惊,Reponse.End()在webfrom和ASP.NET MVC下的表现确实是不同的!

ASP.NET MVC代码:

public ActionResult Index()
{Method0();Method1();Method2();Response.Write("All methods success.");return View("I don't think so.");
}private void Method0()
{Debug.WriteLine("Method 0 process...");bool flag = true;if (!flag){Response.Write("Method 0 failure.");Response.End();}
}private void Method1()
{Debug.WriteLine("Method 1 process...");bool flag = false;if (!flag){Response.Write("Method 1 failure.");Response.End();}
}private void Method2()
{Debug.WriteLine("Method 2 process...");bool flag = false;if (!flag){Response.Write("Method 2 failure.");Response.End();}
}

web页面显示:

调试信息输出:

Response.End()后的代码继续执行,这与之前的认识是没有出入的,接下来看webform。

Webform代码:

protected void Page_Load(object sender, EventArgs e)
{Method0();Method1();Method2();Response.Write("All methods success.");
}private void Method0()
{Debug.WriteLine("Method 0 process...");bool flag = true;if (!flag){HttpContext.Current.Response.Write("Method 0 failure.");System.Web.HttpContext.Current.Response.End();}
}private void Method1()
{Debug.WriteLine("Method 1 process...");bool flag = false;if (!flag){HttpContext.Current.Response.Write("Method 1 failure.");System.Web.HttpContext.Current.Response.End();}
}private void Method2()
{Debug.WriteLine("Method 2 process...");bool flag = true;if (!flag){HttpContext.Current.Response.Write("Method 2 failure.");System.Web.HttpContext.Current.Response.End();}
}

web页面输出:

调试信息:

web页面的输出一致,调试窗口那里可是大不一样。webform并未接着执行Response.End()后的代码,因为抛出了一个ThreadAbortException异常。这时候,我首先想到的是ASP.NET MVC下的Response对象类型是否和ASP.NET不同,导致他们的处理方式不同。

后来发现虽然ASP.NET MVC中的Response类型是HttpResponseBase,但是显式地去调用System.Web.Context.Current.Response.End()结果依旧。通过Reflector查看ASP.NET MVC下HttpResponseBase的实现类HttpResponseWrapper,End方法的实现如图,this_httpResponse是HttpResponse的私有变量。

查到这儿思路一度中断,只好回头去对比调试信息中的表现,从ThreadAbortException这个异常入手,发现在ASP.NET MVC中先调用Response.End(),再调用Thread.CurrentThread.Abort()可以达到webform下调用Response.End()的效果。当然其他异常也能模拟,但是此时发现了一个小问题,就是抛出普通异常的时候和抛出ThreadAbortException异常略有不同。

普通异常的弹出窗口:

调试信息输出:

ThreadAbortException异常没有弹出那个窗口,调试信息中也多了一条信息。

是由于ThreadAbortException是SystemException(系统异常)被特殊对待了吗?

这只是一个衍生出来的疑问,继续刚才的问题,用ThreadAbortException和ASP.NET MVC作为关键字去google搜索,在Will保哥的博客中得到了解答!

具体可以参见这篇博客下的评论和另一篇博客。

经过保哥的指点,通过Reflector去查看源码,证实了是_timeoutState的作用。

HttpResponse.End中代码:

IsInCancellablePeriod属性:

问题得到了解决!~但是我还有一个小疑问,也就是从Reflector中看到End方法的源码,IsInCancellablePeriod是bool类型,但是却判断是否等于null。这怎么也是不合适的吧,是Reflector的解析错误还是其他原因导致的呢?

转载于:https://www.cnblogs.com/v5wa/p/3165367.html

Response.End()在Webform和ASP.NET MVC下的表现差异相关推荐

  1. ASP.NET MVC下的四种验证编程方式[续篇]

    ASP.NET MVC下的四种验证编程方式[续篇] 原文:ASP.NET MVC下的四种验证编程方式[续篇] 在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET ...

  2. ASP.NET MVC下使用AngularJs语言(一):Hello your name

    新春节后,分享第一个教程. 是教一位新朋友全新学习ASP.NET MVC下使用AngularJs语言. 一,新建一个空的Web项目.使用NuGet下载AngularJs和jQuery. 二,配置Bun ...

  3. ASP.NET MVC下基于异常处理的完整解决方案

    ASP.NET MVC下基于异常处理的完整解决方案 参考文章: (1)ASP.NET MVC下基于异常处理的完整解决方案 (2)https://www.cnblogs.com/artech/archi ...

  4. asp.net webform 与asp.net mvc 混合开发项目总结

    公司里的一个web项目 运行速度比较慢(原来是asp.net webform  建立的时候是通过新建网站 不是web项目) 这个项目最早是VS2003 做的时候asp.net也不是很熟悉 订单登记的页 ...

  5. 【原创】关于ASP.NET WebForm与ASP.NET MVC的比较

    WebForm的理解 1. WebForm概念 ASP.NETWebform提供了一个类似于Winform的事件响应GUI模型(event-drivenGUI),隐藏了HTTP.HTML.JavaSc ...

  6. ASP.NET MVC下使用AngularJs语言(三):ng-options

    今天使用angularjs的ng-options实现一个DropDownList下拉列表. 准备ASP.NET MVC的model: public class MobilePhone{public i ...

  7. 在ASP.NET MVC下实现树形导航菜单

    在需要处理很多分类以及导航的时候,树形导航菜单就比较适合.例如在汽车之家上: 页面主要分两部分,左边是导航菜单,右边显示对应的内容.现在,我们就在ASP.NET MVC 4 下临摹一个,如下: 实现的 ...

  8. ASP.NET MVC下的异步Action的定义和执行原理

    Visual Studio提供的Controller创建向导默认为我们创建一个继承自抽象类Controller的Controller类型,这样的Controller只能定义同步Action方法.如果我 ...

  9. ASP.NET MVC下的四种验证编程方式

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定 ...

最新文章

  1. Spring笔记——8.基于XML Schema的简化配置
  2. pku 3411 Paid Roads DFS+灵活技巧卡节点访问次数
  3. 解决在AX 2009中删除公司时提示:未授权用户##删除表“DEL_PBATRANSLATECONSISTOF”中的记录...
  4. 牛客练习赛34 E little w and Digital Root(数位dp)
  5. bitcoin转账api,python2.7
  6. cheat engine 将选中目标的函数_EXCEL函数与公式剖析:IF
  7. linux rpm安装mysql5.7.*密码策略,访问策略等常见问题
  8. ORA-28002 the password will expire
  9. 基于dpdk的用户态协议栈f-stack实现分析
  10. 计算机体系结构.是系统结构还是体系结构
  11. java udp转发_JAVA NIO udp 实现 群转发
  12. GET请求参数中文乱码的解决办法
  13. 行为识别 - Temporal Pyramid Network for Action Recognition
  14. mysql 序系列化_J2SE中的序默认序列化_MySQL
  15. Windows系统SVG图片预览插件
  16. sparql学习 sparql示例 dbpedia在线验证
  17. 信息化系统要如何选型?
  18. 微信转账php开发心得
  19. VMware 无法安装 VMware Tools, 提示VMCI,内存驱动
  20. 代码应用jFinal+AngularJs未来javaEE开发的趋势——程序员的福音

热门文章

  1. diy 单片机 自动浇花_造个自动浇花装置(完)
  2. 小黄鸭c语言程序代码,新年的小黄鸭 - 题目 - Universal Online Judge
  3. avl树 php,PHP实现平衡二叉树(AVL树)
  4. gradle——eclipse中安装与web项目创建
  5. VirtualBox扩容失败-Progress state: VBOX_E_NOT_SUPPORTED
  6. 网页游戏为什么容易赚钱?(From:07073)
  7. 1.ElementUI中table的sortable使用
  8. 【java学习之路】(数据结构篇)004.递归和二叉搜索树
  9. linux系统怎么ping命令,Linux系统下的ping命令的使用
  10. sublime快速打开终端terminal