3月 29

问题:

try,finally中的执行顺序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace blog.wx6.org
{ 
    class Program
    { 
        public static void Main(string[] args)
        {
            Console.WriteLine("return------{0}", aa());
        }
        static int aa()
        {
            int a = 1;
            try
            {
                a = a + 1;
                return a;
            }
            finally
            {
                a = a + 5;
                Console.WriteLine("finally-----{0}", a);
            }
        }
    } 
}

执行结果

finally—–7

return——2

说明:

//try-finally-return()的执行顺序
//try—–>>>>return()—->>>>finally

在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于a的局部变量中去,执行完finally之后,再从中取出返回结果,
因此,即使finally中对变量a进行了改变,但是不会影响返回结果。

written by ocean

3月 29

命名参数

命名参数是把参数附上参数名称,这样在调用方法的时候不必按照原来的参数顺序填写参数,只需要对应好参数的名称也能完成方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace blog.wx6.org
{
    class Program
    { 
        /// 可选参数  命名参数
        /// </summary>
        static void Main(string[] args)
        {
            Console.WriteLine(ShowComputer(disk:100, cpu: "i3 370M", ram: "2G")); 
            Console.Read();
        }
 
        private static string ShowComputer(string cpu = "i3 370M", string ram = "4G", int disk =320)
        {
            return "My computer ... \nCpu:" + cpu + "\nRam:" + ram + "\nDisk:" + disk + "G\n";
        } 
    } 
}

命名参数如果只是改变参数的顺序,这样的意义并不大,我们没有必要为了改变顺序而去用命名参数,他与可选参数结合才能显示出他真正的意义。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace blog.wx6.org
{
    class Program
    { 
        /// 可选参数  命名参数
        /// </summary>
        static void Main(string[] args)
        {
            Console.WriteLine(ShowComputer(disk:100)); 
            Console.Read();
        }
 
        private static string ShowComputer(string cpu = "i3 370M", string ram = "4G", int disk =320)
        {
            return "My computer ... \nCpu:" + cpu + "\nRam:" + ram + "\nDisk:" + disk + "G\n";
        } 
    } 
}

written by ocean

3月 23

之前写过了

本博客前台用的是 SyntaxHighlighter

http://blog.wx6.org/2013/347.htm

使用延迟加载之后  凡是有代码的html页面才会加载相应的css和javascript

    <link href="/template/syntaxhighlighter/shcoredefault.css" rel="stylesheet" type="text/css" />

    <script src="/template/syntaxhighlighter/shcore.js"></script>

但是实际使用下来发现,在chrome下行号对齐没有问题,ie下会出现行号和代码错位的问题

written by ocean

3月 13

反射经常用

测试一下

需要反射的类名和接口

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
   
namespace blog.wx6.org 
{ 
    public interface ITest 
    { 
         int Total(int a, int b); 
    } 
    public class Test : ITest 
    { 
        public int Total(int a, int b) 
        { 
            return a + b; 
        } 
    } 
}

测试方法

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 
using System.Diagnostics; 
   
namespace blog.wx6.org 
{ 
    class Program 
    { 
        private const BindingFlags flag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public; 
   
        static void Main(string[] args) 
        { 
            int count = 1000000; 
   
            Stopwatch sw = Stopwatch.StartNew(); 
            for (int i = 0; i < count; i++) 
            { 
                InvokeByReflect(); 
            } 
            Console.WriteLine("反射方式调用: " + sw.Elapsed); 
   
            sw = Stopwatch.StartNew(); 
            for (int i = 0; i < count; i++) 
            { 
                InvokeByCreateDelegate(); 
            } 
            Console.WriteLine("委托方式调用: " + sw.Elapsed); 
   
   
            sw = Stopwatch.StartNew(); 
            for (int i = 0; i < count; i++) 
            { 
                InvokeByDynamicKeyword(); 
            } 
            Console.WriteLine("动态关键字调用: " + sw.Elapsed); 
   
            sw = Stopwatch.StartNew(); 
            for (int i = 0; i < count; i++) 
            { 
                InvokeByDynamicKeywordAndInterface(); 
            } 
            Console.WriteLine("动态关键字接口调用: " + sw.Elapsed); 
   
   
            Console.Read(); 
   
        } 
   
        /// <summary> 
        /// 使用委托 
        /// </summary> 
        public static void InvokeByCreateDelegate() 
        { 
            Test obj = (Test)Activator.CreateInstance(typeof(Test)); 
            MethodInfo methodInfo = typeof(Test).GetMethod("Total", flag); 
   
            Func<int, int, int> delegateMethodInfo = (Func<int, int, int>)Delegate.CreateDelegate(typeof(Func<int, int, int>), obj, methodInfo); 
            int result = delegateMethodInfo(10, 10); 
        } 
   
        /// <summary> 
        /// 使用反射 
        /// </summary> 
        public static void InvokeByReflect() 
        { 
            Test obj = (Test)Activator.CreateInstance(typeof(Test)); 
            MethodInfo mi = typeof(Test).GetMethod("Total", flag); 
   
            object result = mi.Invoke(obj, new object[] { 10, 10 }); 
        } 
   
        /// <summary> 
        /// 动态关键字调用 
        /// </summary> 
        public static void InvokeByDynamicKeyword() 
        { 
            dynamic obj = (Test)Activator.CreateInstance(typeof(Test)); 
            int result = obj.Total(10, 10); 
        } 
   
        /// <summary> 
        /// 动态关键字接口调用 
        /// </summary> 
        public static void InvokeByDynamicKeywordAndInterface() 
        { 
            ITest obj = (ITest)Activator.CreateInstance(typeof(Test)); 
            int result = obj.Total(10, 10); 
        } 
   
    } 
}

运行结果

反射方式调用: 00:00:02.3413084
委托方式调用: 00:00:12.6151307
动态关键字调用: 00:00:00.9427191
动态关键字接口调用: 00:00:00.3849380
可以看出来,在反射方法不缓存的情况下,用dynamic关键字加接口的方式效率最高


刚才的测试因为没有缓存的原因得到的,相当于每次都需要创建委托调用,现在改变一下,缓存起来

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
 
namespace blog.wx6.org
{
    class Program
    {
        private const BindingFlags flag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
 
        static void Main(string[] args)
        {
            int count = 1000000;
 
            Stopwatch sw = Stopwatch.StartNew();
            Test objReflect = (Test)Activator.CreateInstance(typeof(Test));
            MethodInfo methodInfoReflect = typeof(Test).GetMethod("Total", flag);
            for (int i = 0; i < count; i++)
            {  
                object result = methodInfoReflect.Invoke(objReflect, new object[] { 10, 10 });
            }
            Console.WriteLine("反射方式调用: " + sw.Elapsed);
 
 
 
 
            sw = Stopwatch.StartNew();
            Test objDelegate = (Test)Activator.CreateInstance(typeof(Test));
            MethodInfo delegateMethod = typeof(Test).GetMethod("Total", flag);
            Func<int, int, int> delegateMethodInfo = (Func<int, int, int>)Delegate.CreateDelegate(typeof(Func<int, int, int>), objDelegate, delegateMethod);
            for (int i = 0; i < count; i++)
            {
                int result = delegateMethodInfo(10, 10);
            }
            Console.WriteLine("委托方式调用: " + sw.Elapsed);
 
 
            sw = Stopwatch.StartNew();
            dynamic objDynamicKeyword = (Test)Activator.CreateInstance(typeof(Test));
            for (int i = 0; i < count; i++)
            { 
                int result = objDynamicKeyword.Total(10, 10);
 
            }
            Console.WriteLine("动态关键字调用: " + sw.Elapsed);
 
            sw = Stopwatch.StartNew();
            ITest objDynamicKeywordAndInterface = (ITest)Activator.CreateInstance(typeof(Test));
            for (int i = 0; i < count; i++)
            { 
                int result = objDynamicKeywordAndInterface.Total(10, 10); 
            }
            Console.WriteLine("动态关键字接口调用: " + sw.Elapsed);
 
 
            Console.Read();
 
        } 
    }
}

执行结果

反射方式调用: 00:00:01.5410770

委托方式调用: 00:00:00.0425065

动态关键字调用: 00:00:00.3413856

动态关键字接口调用: 00:00:00.0436606

可以看出来,委托调用和动态关键字接口的调用方式效率最优

written by ocean

3月 06

之前一直用的是json的,这次要用下xml,发现基本是一样的

废话不多,记录如下

static void Main(string[] args)
{
    TestInfo testInfo = new TestInfo();
    testInfo.Name = "我是根";
    ItemInfo itemInfo = new ItemInfo();
    itemInfo.IsLeaf = true;
    itemInfo.Url = "http://www.wx6.rog";
    testInfo.Items = new List<ItemInfo>();
    testInfo.Items.Add(itemInfo);
 
 
    //将对象序列化成xml
    string xml = string.Empty;
    using (StringWriter sw = new StringWriter())
    {
        XmlSerializer xz = new XmlSerializer(testInfo.GetType());
        xz.Serialize(sw, testInfo);
        xml = sw.ToString();
    }
    Console.WriteLine(xml);
 
    //反序列化
    TestInfo newTestInfo = new TestInfo();
    using (StringReader sr = new StringReader(xml))
    {
        XmlSerializer xz = new XmlSerializer(testInfo.GetType());
        newTestInfo = (TestInfo)xz.Deserialize(sr);
    }
 
    Console.Read();
 
}

辅助类

public class TestInfo
{
    public string Name { get; set; }
    public List<ItemInfo> Items { get; set; }
}
public class ItemInfo
{
    public List<ItemInfo> Itrems { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public bool IsLeaf { get; set; }
}

 

written by ocean

3月 06

没学计算机专业最大的不足就是算法

居然以前没听过KMP匹配算法

这次做这个东西试了一下,发现真的很好用,记录如下

 

/// <summary> 
/// KMP算法实现匹配 
/// </summary> 
/// <param name="input"></param> 
/// <param name="content"></param> 
/// <param name="max"></param> 
/// <returns></returns> 
public static List<string> KMPGetUser(string input, string content,int max) 
{ 
    if (content == null || content.Length == 0) 
        return null; 
    if (input == null || input.Length == 0) 
        return null; 
    if (content[0] != ';') 
        content = ";" + content; 
    if (content[content.Length - 1] != ';') 
        content += ";"; 
    List<string> result = new List<string>(); 
    int start = -1; 
    int end = -1; 
    int i = 0; 
    int j = 0; 
    for (; i < content.Length; i++) 
    { 
        if (content[i] == ';') 
        { 
            if (start > -1 && end > -1) 
            { 
                string item = string.Empty; 
                for (int index = start+1; index < end; index++) 
                { 
                    item += content[index].ToString(); 
                } 
                result.Add(item); 
                if (result.Count >= max) 
                    break; 
                end = -1; 
            }  
            start = i; 
            j = 0; 
            continue; 
        } 
        if (content[i] == input[j])//相同 
        { 
            bool isOK = true; 
            j++; 
            i++; 
            while (j < input.Length && isOK) 
            { 
                if (content[i] != input[j]) 
                { 
                    isOK = false; 
                } 
                i++; 
                j++; 
            } 
            if (isOK)//匹配成功 
            { 
                while (content[i] != ';') { 
                    i++; 
                } 
                end = i; 
                i--;  
            } 
            j = 0; 
        }  
    }  
    return result; 
}

 

written by ocean

3月 04

因为经常要做本地开发,所以经常需要做hosts的修改

写了一个bat文化,可以快速切换

hosts.bak

127.0.0.1 localhost

hosts.dev.bak

#dev#

127.0.0.1 localhost

#127.0.0.1wx6.org

#127.0.0.1www.wx6.org

127.0.0.1ciyu.wx6.org

127.0.0.1blog.wx6.org

Bat切换文件

@echo off
 
:a
cls
findstr "dev" "C:\Windows\System32\drivers\etc\hosts"&&goto b||goto c
ipconfig /flushdns
 
:b
cls
echo 切换到正常模式
cd /d %windir%\system32\drivers\etc 
copy /Y hosts.bak hosts
pause
goto a
 
:c
cls
echo 切换到开发模式
cd /d %windir%\system32\drivers\etc 
copy /Y hosts.dev.bak hosts
pause
goto a
 
 
cd /d %windir%\system32\drivers\etc 
copy /Y hosts_local.bak hosts

written by ocean

3月 04

同事推荐了一篇帖子

http://engineering.xueqiu.com/blog/2013/02/27/implementing-bigpipe-in-nodejs/

主要是讲Facebook的Bigpipe技术的

学习了一下思想,写了一个C#版本的

对不对不知道,反正可以实现效果

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BigPipe.aspx.cs" Inherits="TestDemo.WebApplication.BigPipe" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>     
    <div><div>第一块</div><div style=" min-height:200px" id="div1">加载中</div> </div>
     
     <div><div>第二块</div><div style=" min-height:200px" id="div2">加载中</div> </div>
 
     <div><div>第三块</div><div style=" min-height:200px" id="div3">加载中</div> </div>
 
     <%
         ResponseBuffer();
      %>
 
</body>
</html>

后台代码

public partial class BigPipe : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    { 
    }
 
 
 
 
    public void ResponseBuffer()
    {
        Response.Flush();
 
 
 
        Thread.Sleep(1000);
        Response.Write("<script>document.getElementById('div1').innerHTML = '我是内容1,我已经加载完成';</script>");
        Response.Flush();
 
 
        Thread.Sleep(1000);
        Response.Write("<script>document.getElementById('div2').innerHTML = '我是内容2,我已经加载完成';</script>");
        Response.Flush();
 
 
 
        Thread.Sleep(1000);
        Response.Write("<script>document.getElementById('div3').innerHTML = '我是内容3,我已经加载完成';</script>");
        Response.Flush();
 
          
    }
 
}

实质上是 缓冲池中的数据生成一部分就输出一部分,输出之后用JS填充到HTML中

这样就可以做到整个页面框架快速下载,模块后续加载

后来又搜了一篇

http://www.cnblogs.com/BearsTaR/archive/2010/06/18/facebook_html_chunk.html

更先进一些,不过本质原理是一样的

还有一种在服务器端多模块加载的形式pagelet,回头再写一篇吧

written by ocean