Thursday, July 26, 2012

Response.Redirect throws an Thread was being aborted

original from:
http://briancaos.wordpress.com/2010/11/30/response-redirect-throws-an-thread-was-being-aborted/

Response.Redirect causes the browser to redirect to a different URL. It does so by sending a 302 – Object Moved to the browser, requesting it to do another roundtrip to the new page. Here is an example:
protected void Page_Load(object sender, EventArgs e)
{
  try
       {
           if (somethingIsTrue)
          Response.Redirect("http://", true);
       }
catch (Exception ex)
{
           // All exceptions are caught and written
           // to a log file
}
}
But here
 is something I didn’t know. When doing the Response.Redirect, .net will automatically throw an System.Threading.ThreadAbortException when the redirect is called. Apparently this is by design (although I’m nor sure I agree with the design).
The code above will write a log line for each time the Response.Redirect is called. This will flood my log file.
There are 4 solutions.
1) Set the EndResponse (the 2nd parameter) to false. The thread is aborted when the response is ended, so if you do not end the response, no abortion is done (this is untested, but according to several blogs valid).

2) Move the Response.Redirect outside the try/catch block.

3) Filter the exceptions. Do nothing if the ThreadAbortException occurs:

protected void Page_Load(object sender, EventArgs e)
{
 try
{
 if (somethingIsTrue)
Response.Redirect("http://www.pentia.dk/", true);
}
catch (ThreadAbortException ex1)
{
// do nothing
}
catch (Exception ex2)
{
// All remaining exceptions are caught and written
 // to a log file
}
}

4) Do not use Response.Redirect. Instead, modify the response headers (this is the rather stupid solution, but I have added it to show that you can redirect without using Response.Redirect):

Response.Clear();
Response.Status = "302 Object Moved";
Response.RedirectLocation = "http://www.pentia.dk/";
Response.End();

Thursday, July 19, 2012

break/continue/rturn

break 用法
break 语句用于终止最近的封闭循环或它所在的switch 语句。控制传递给终止语句后面的语句(如果有的话)。
说明
通常在 switch 语句和 while、for、for...in、或 do...while 循环中使用 break 语句。 最一般的是在 switch 语句中,但它可在任何语句中使用,无论是简单语句还是复合语句。
执行 break 语句会退出当前循环或语句,并开始执行紧接着的语句
break 示例
-----------------------------------------------------------------------------


在此例中,条件语句包含一个应该从 1 计数到 100 的计数器;
但 break 语句在计数达到 4 后终止循环。
// statements_break.cs
using System;
class BreakTest
{
static void Main()
{
for (int i = 1; i <= 100; i++)
{
if (i == 5)
{
break;
}
Console.WriteLine(i);
}
}
}
输出
1
2
3
4
----------------------------------------
下面的示例演示 break 在switch语句中的用法。
// statements_break2.cs
// break and switch
using System;
class Switch
{
static void Main()
{
Console.Write("Enter your selection (1, 2, or 3): ");
string s = Console.ReadLine();
int n = Int32.Parse(s);

switch (n)
{
case 1:
Console.WriteLine("Current value is {0}", 1);
break;
case 2:
Console.WriteLine("Current value is {0}", 2);
break;
case 3:
Console.WriteLine("Current value is {0}", 3);
break;
default:
Console.WriteLine("Sorry, invalid selection.");
break;
}
}
}输入1示例输出Enter your selection (1, 2, or 3): 1Current value is 1如果输入了 4,则输出为: Enter your selection (1, 2, or 3): 4Sorry, invalid selection.


break语句:
break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句。由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的break语句才是合法的。

如果一个循环的终止条件非常复杂,那么使用break语句来实现某些条件比用一个循环表达式来表达所有的条件容易得多。
for(var i=1;i<=10;i++)
{
if(i==6) break;
document.write(i);
}
//输出结果:12345

continue语句:
continue语句和break语句相似。所不同的是,它不是退出一个循环,而是开始循环的一次新迭代。
continue语句只能用在while语句、
do/while语句、for语句、或者for/in语句的循环体内,在其它地方使用都会引起错误!

for(var i=1;i<=10;i++)
{ if(i==6) continue;
document.write(i);
}
//输出结果:1234578910


return语句:
return语句就是用于指定函数返回的值。return语句只能出现在函数体内,出现在代码中的其他任何地方都会造成语法错误!
当执行return语句时,即使函数主体中还有其他语句,函数执行也会停止!

ref and out

ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。

使用ref前必须对变量赋值,out不用。

out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

区别可以参看下面的代码:

using System;
class TestApp
{
 static void outTest(out int x, out int y)
 {//离开这个函数前,必须对x和y赋值,否则会报错。
  //y = x;
  //上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行
  x = 1;
  y = 2;
 }
 static void refTest(ref int x, ref int y)
 {
  x = 1;
  y = x;
 }
 public static void Main()
 {
  //out test
  int a,b;
  //out使用前,变量可以不赋值
  outTest(out a, out b);
  Console.WriteLine("a={0};b={1}",a,b);
  int c=11,d=22;
  outTest(out c, out d);
  Console.WriteLine("c={0};d={1}",c,d);

  //ref test
  int m,n;
  //refTest(ref m, ref n);
  //上面这行会出错,ref使用前,变量必须赋值

  int o=11,p=22;
  refTest(ref o, ref p);
  Console.WriteLine("o={0};p={1}",o,p);
 }
}