2019-10-31 15:32:00 xbfengyu 阅读数 96
  • C# For Unity系列之进阶篇

    整体介绍:       本进阶篇面向的学员不再是完全的编程“小白”,而是具备一定C#编程经验,需要进一步查漏补缺、或者需要进一步全面完善自己C#编程知识体系的广大Unity学员。相信通过本进阶篇的学习,可以使得Unity初中级开发人员对于编程语言的掌握更进一步;对于开发中大型游戏项目,在编程语言这一层级进一步打下坚实的语言基础。 “中级/进阶篇”讲解特点与内容:          本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。         "进阶篇"是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。   C#“进阶篇”教学详细说明如下: 1: IO操作与序列化       学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。 2: 正则表达式       学习正则表达式的强大作用与常用原字符的含义与应用场景。 3: 深入委托与事件       学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。 4: 反射与特性       学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。   5: Linq 查询表达式      学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable<T>) 以及SQL数据库、XML文档方面的强大查询功能。       6: 多线程      学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。      7: Socket套接字通讯      学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。 温习提示:             本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      一、热更新系列(技术含量:中高级): A:《lua热更新技术中级篇》 https://edu.csdn.net/course/detail/27087 B:《热更新框架设计之Xlua基础视频课程》 https://edu.csdn.net/course/detail/27110 C:《热更新框架设计之热更流程与热补丁技术》 https://edu.csdn.net/course/detail/27118 D:《热更新框架设计之客户端热更框架(上)》 https://edu.csdn.net/course/detail/27132 E:《热更新框架设计之客户端热更框架(中)》 https://edu.csdn.net/course/detail/27135 F:《热更新框架设计之客户端热更框架(下)》 https://edu.csdn.net/course/detail/27136 二:框架设计系列(技术含量:中级):  A:《游戏UI界面框架设计系列视频课程》 https://edu.csdn.net/course/detail/27142 B:《Unity客户端框架设计PureMVC篇视频课程(上)》 https://edu.csdn.net/course/detail/27172 C:《Unity客户端框架设计PureMVC篇视频课程(下)》 https://edu.csdn.net/course/detail/27173 D:《AssetBundle框架设计_框架篇视频课程》 https://edu.csdn.net/course/detail/27169 三、Unity脚本从入门到精通(技术含量:初级) A:《C# For Unity系列之入门篇》 https://edu.csdn.net/course/detail/4560 B:《C# For Unity系列之基础篇》 https://edu.csdn.net/course/detail/4595 C: 《C# For Unity系列之中级篇》 https://edu.csdn.net/course/detail/24422 D:《C# For Unity系列之进阶篇》 https://edu.csdn.net/course/detail/24465 四、虚拟现实(VR)与增强现实(AR):(技术含量:初级) A:《虚拟现实之汽车仿真模拟系统 》 https://edu.csdn.net/course/detail/26618 五、Unity基础课程系列(技术含量:初级)  A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》   https://edu.csdn.net/course/detail/24643 B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》 https://edu.csdn.net/course/detail/24645  C:《Unity ECS(二) 小试牛刀》 https://edu.csdn.net/course/detail/27096 六、Unity ARPG课程(技术含量:初中级): A:《MMOARPG地下守护神_单机版实战视频课程(上部)》 https://edu.csdn.net/course/detail/24965 B:《MMOARPG地下守护神_单机版实战视频课程(中部)》 https://edu.csdn.net/course/detail/24968 C:《MMOARPG地下守护神_单机版实战视频课程(下部)》 https://edu.csdn.net/course/detail/24979

    1692 人正在学习 去看看 刘国柱

转载:https://www.cnblogs.com/ruicky/p/4597439.html

  因业务的需要,有这么个需求,需要前台的JS传参调用C#后台的方法。现在有这么个方法可以解决,整理如下。

  首先,先说一下基本实现,前台用Jquery的ajax将其中的URL后加方法,然后在Data中传递参数。在返回的Data中 获取到数据,并做相应的处理。而后端呢,则是在对应的方法加标记WebMethod。

  前端JS:

 $.ajax({
        type: "post",
        dataType: "json",
        data: "{jsTime:'" + jsTime + "'}",
        contentType: "application/json; charset=utf-8",
        url: "navigationbars.ascx/getMemInfo",
        success: function (data) {
            if (data.d != "") {
                //截取该对象,获取字符串中的Contents,mid
                var entity = data.d;
                var pairs = entity.split(',');
                var mid = pairs[0].value;
                var content = pairs[1].value;
                }
        },
        error: function () {
            alert("ajax方法Error!");
        }
    });

  后台方法:

 [WebMethod]
    public static string getMemInfo(string jsTime)
{
  //处理逻辑代码
  return "";    
}
2008-07-09 20:14:00 moshuchao 阅读数 4865
  • C# For Unity系列之进阶篇

    整体介绍:       本进阶篇面向的学员不再是完全的编程“小白”,而是具备一定C#编程经验,需要进一步查漏补缺、或者需要进一步全面完善自己C#编程知识体系的广大Unity学员。相信通过本进阶篇的学习,可以使得Unity初中级开发人员对于编程语言的掌握更进一步;对于开发中大型游戏项目,在编程语言这一层级进一步打下坚实的语言基础。 “中级/进阶篇”讲解特点与内容:          本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。         "进阶篇"是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。   C#“进阶篇”教学详细说明如下: 1: IO操作与序列化       学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。 2: 正则表达式       学习正则表达式的强大作用与常用原字符的含义与应用场景。 3: 深入委托与事件       学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。 4: 反射与特性       学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。   5: Linq 查询表达式      学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable<T>) 以及SQL数据库、XML文档方面的强大查询功能。       6: 多线程      学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。      7: Socket套接字通讯      学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。 温习提示:             本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      一、热更新系列(技术含量:中高级): A:《lua热更新技术中级篇》 https://edu.csdn.net/course/detail/27087 B:《热更新框架设计之Xlua基础视频课程》 https://edu.csdn.net/course/detail/27110 C:《热更新框架设计之热更流程与热补丁技术》 https://edu.csdn.net/course/detail/27118 D:《热更新框架设计之客户端热更框架(上)》 https://edu.csdn.net/course/detail/27132 E:《热更新框架设计之客户端热更框架(中)》 https://edu.csdn.net/course/detail/27135 F:《热更新框架设计之客户端热更框架(下)》 https://edu.csdn.net/course/detail/27136 二:框架设计系列(技术含量:中级):  A:《游戏UI界面框架设计系列视频课程》 https://edu.csdn.net/course/detail/27142 B:《Unity客户端框架设计PureMVC篇视频课程(上)》 https://edu.csdn.net/course/detail/27172 C:《Unity客户端框架设计PureMVC篇视频课程(下)》 https://edu.csdn.net/course/detail/27173 D:《AssetBundle框架设计_框架篇视频课程》 https://edu.csdn.net/course/detail/27169 三、Unity脚本从入门到精通(技术含量:初级) A:《C# For Unity系列之入门篇》 https://edu.csdn.net/course/detail/4560 B:《C# For Unity系列之基础篇》 https://edu.csdn.net/course/detail/4595 C: 《C# For Unity系列之中级篇》 https://edu.csdn.net/course/detail/24422 D:《C# For Unity系列之进阶篇》 https://edu.csdn.net/course/detail/24465 四、虚拟现实(VR)与增强现实(AR):(技术含量:初级) A:《虚拟现实之汽车仿真模拟系统 》 https://edu.csdn.net/course/detail/26618 五、Unity基础课程系列(技术含量:初级)  A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》   https://edu.csdn.net/course/detail/24643 B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》 https://edu.csdn.net/course/detail/24645  C:《Unity ECS(二) 小试牛刀》 https://edu.csdn.net/course/detail/27096 六、Unity ARPG课程(技术含量:初中级): A:《MMOARPG地下守护神_单机版实战视频课程(上部)》 https://edu.csdn.net/course/detail/24965 B:《MMOARPG地下守护神_单机版实战视频课程(中部)》 https://edu.csdn.net/course/detail/24968 C:《MMOARPG地下守护神_单机版实战视频课程(下部)》 https://edu.csdn.net/course/detail/24979

    1692 人正在学习 去看看 刘国柱
             Javascript调用C#代码的方法网上介绍了很多种方法,也很详细,但没有向C#传递参数的方法。今天刚好用到,搞了半天才搞出来(其实我很笨)。下面说一下具体实现的方法。 一、使用HiddenField 控件。      HiddenField控件顾名思义就是隐藏输入框的服务器控件,它能让你保存那些不需要显示在页面上的且对安全性要求不高的数据。也许这个时候应该有这么一个疑问,为什么有了ViewState、Session和Cookie等状态保存机制,还需要用起HiddenField呢?    增加HiddenField,其实是为了让整个状态管理机制的应用程度更加全面。因为不管是ViewState、Cookie还是Session,都有 其失效的时候,比如用户因某种需求要求设置ViewState为false,或者环境条件限制使用Cookie,或者用户长时间没有动作导致 Session过期等等,那这个时候HiddenField无疑是最佳选择。   HiddenField控件的作用简单的说是用于存 储需要在向服务器的发送间保持的值。它作为 <input type= "hidden"/> 元素呈现,并且通过添加runat=”server”就可以使它成为标准的HTML服务器控件。下面列出的是ASP.NET HiddenField Web服务器控件可以使用的属性和事件。       
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><asp:Button

        <a href="javascript:TestPostValue('test')">Test Post By HiddenField</a><br/>

    <asp:HiddenField ID="hidden" runat="server" />



...

    <script type="text/javascript">

   function TestPostValue(value)

{

    document.getElementById("hidden").value=value;

    document.getElementById("Button1").click();

}

    </script>
        protected void Button1_Click(object sender, EventArgs e)

        {

            Response.Write(hidden.Value);

        }


二、利用Cookies

Cookie的用法也和ASP中差不多。

比如我们建立一个名为aspcn,值为飞刀的cookie HttpCookie cookie = new HttpCookie["aspcn"]; cookie.Value = "飞刀"; Response.AppendCookie(cookie); 我们取出Cookie值也很简单 HttpCookie cookie = Request.Cookies["aspcn"]; cookieValue = cookie.Value; 有时候我们想在一个Cookie中储存多个信息,那也没有问题。比如我们在名为aspcn的cookie下加多个信息 HttpCookie cookie = new HttpCookie("aspcn"); cookie.Values.Add("webmaster","飞刀"); cookie.Values.Add("writer","beige"); cookie.Values.Add("LinkColor","blue"); Response.AppendCookie(cookie); 取出信息也一样简单 HttpCookie cookie = Request.Cookies["aspcn"]; value1 = cookies.Values["webmaster"]; value2 = cookies.Values["writer"];

View State

这是一个新出来的东东,用法和Session一样,他的主要用途是记录Web Control的状态。虽然是新出来的,但是和Application、Session的用法没有什么区别,所以也不想详细讲解了。 State["DropLoadIndex"] = 0 ; 基本用法如上:),但是请记住,他保存在的信息只能在一个aspx文件中使用。出去后,这个就没有用了,因为他的用途只是保存WEB控件的状态。

我的实现代码:

<asp:Button         ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />

        <a href="javascript:TestPostByCookies('Test')">Test Post By Cookies</a>

function TestPostByCookies(value)

{

    SetCookie("myCookie",value);

    document.getElementById("Button2").click();

}





//写cookies函数 作者:翟振凯

function SetCookie(name,value)//两个参数,一个是cookie的名子,一个是值

{

    var Days = 30; //此 cookie 将被保存 30 天

    var exp  = new Date();    //new Date("December 31, 9998");

    exp.setTime(exp.getTime() + Days*24*60*60*1000);

    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();

}

function getCookie(name)//取cookies函数        

{

    var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));

     if(arr != null) return unescape(arr[2]); return null;



}

function delCookie(name)//删除cookie

{

    var exp = new Date();

    exp.setTime(exp.getTime() - 1);

    var cval=getCookie(name);

    if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString();

}

        protected void Button2_Click(object sender, EventArgs e)

        {

            HttpCookie cook =  Request.Cookies["myCookie"];

            Response.Write(cook.Value);

        }

 

                                
2017-09-01 10:01:55 SmallXianNotImmortal 阅读数 1114
  • C# For Unity系列之进阶篇

    整体介绍:       本进阶篇面向的学员不再是完全的编程“小白”,而是具备一定C#编程经验,需要进一步查漏补缺、或者需要进一步全面完善自己C#编程知识体系的广大Unity学员。相信通过本进阶篇的学习,可以使得Unity初中级开发人员对于编程语言的掌握更进一步;对于开发中大型游戏项目,在编程语言这一层级进一步打下坚实的语言基础。 “中级/进阶篇”讲解特点与内容:          本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。         "进阶篇"是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。   C#“进阶篇”教学详细说明如下: 1: IO操作与序列化       学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。 2: 正则表达式       学习正则表达式的强大作用与常用原字符的含义与应用场景。 3: 深入委托与事件       学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。 4: 反射与特性       学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。   5: Linq 查询表达式      学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable<T>) 以及SQL数据库、XML文档方面的强大查询功能。       6: 多线程      学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。      7: Socket套接字通讯      学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。 温习提示:             本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      一、热更新系列(技术含量:中高级): A:《lua热更新技术中级篇》 https://edu.csdn.net/course/detail/27087 B:《热更新框架设计之Xlua基础视频课程》 https://edu.csdn.net/course/detail/27110 C:《热更新框架设计之热更流程与热补丁技术》 https://edu.csdn.net/course/detail/27118 D:《热更新框架设计之客户端热更框架(上)》 https://edu.csdn.net/course/detail/27132 E:《热更新框架设计之客户端热更框架(中)》 https://edu.csdn.net/course/detail/27135 F:《热更新框架设计之客户端热更框架(下)》 https://edu.csdn.net/course/detail/27136 二:框架设计系列(技术含量:中级):  A:《游戏UI界面框架设计系列视频课程》 https://edu.csdn.net/course/detail/27142 B:《Unity客户端框架设计PureMVC篇视频课程(上)》 https://edu.csdn.net/course/detail/27172 C:《Unity客户端框架设计PureMVC篇视频课程(下)》 https://edu.csdn.net/course/detail/27173 D:《AssetBundle框架设计_框架篇视频课程》 https://edu.csdn.net/course/detail/27169 三、Unity脚本从入门到精通(技术含量:初级) A:《C# For Unity系列之入门篇》 https://edu.csdn.net/course/detail/4560 B:《C# For Unity系列之基础篇》 https://edu.csdn.net/course/detail/4595 C: 《C# For Unity系列之中级篇》 https://edu.csdn.net/course/detail/24422 D:《C# For Unity系列之进阶篇》 https://edu.csdn.net/course/detail/24465 四、虚拟现实(VR)与增强现实(AR):(技术含量:初级) A:《虚拟现实之汽车仿真模拟系统 》 https://edu.csdn.net/course/detail/26618 五、Unity基础课程系列(技术含量:初级)  A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》   https://edu.csdn.net/course/detail/24643 B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》 https://edu.csdn.net/course/detail/24645  C:《Unity ECS(二) 小试牛刀》 https://edu.csdn.net/course/detail/27096 六、Unity ARPG课程(技术含量:初中级): A:《MMOARPG地下守护神_单机版实战视频课程(上部)》 https://edu.csdn.net/course/detail/24965 B:《MMOARPG地下守护神_单机版实战视频课程(中部)》 https://edu.csdn.net/course/detail/24968 C:《MMOARPG地下守护神_单机版实战视频课程(下部)》 https://edu.csdn.net/course/detail/24979

    1692 人正在学习 去看看 刘国柱


    之前说了把百度地图引入.net网站之中的方法,那还有一个问题就是,如何把后台数据库中的位置信息传到地图页面将其显示出来呢?这就涉及到了JS与C#后台的数据交互问题了,今天我们先来简单的说一下JS对后台方法数据的调用。

   
1.用一个按钮控件,将把需要前台调用的方法体写入该按钮的button_click事件中

  
   前台JS函数为:

document.getElementById("按钮ID").click();

   前台调用按钮的单击事件,间接的访问了后台的函数方法。


  2.后台函数声明如下:

public string Test()
    {
        return("调用数据")
     }

    前台在脚本中用<%=function()%>方法调用函数。如下:

var a= "<%=Test()%>";
alert(a);

当然,你也阔以尝试一下,在Test函数中写入其它的处理内容,也是也可以正常执行的。


  3.直接访问参数

   后台设置可访问的变量,即权限设为Public,如:

public string test;

   则前台在页面脚本中可以用下面的方式访问上述test参数;

var a="<%=test%>";

  现在就可以非常方便的将后台的位置信息传递给前台地图界面显示坐标信息啦~

  
注:当然前后台的数据交互不要忘记我们之前说过的ajax哦~~~

  小例子;

   后台函数没啥,就传递了几个位置信息,不过我把多个位置信息组合了一下,压缩给了一个字符串。(我就贴一下主要代码吧,方便理解)

  

 private StringBuilder sb_Line = new StringBuilder();

 public string string_Line;

 //遍历DataSet集合,获取有关信息合成字符串(我的数据从数据库读出来的)
 //最后完成的组合形式例如:1|河北|2345,1234;2|河南|1344,7890 前台获取字符串后还需要解析的(数据是瞎写的。。。)

 for (int i = 0; i < ds_line.Tables[0].Rows.Count; i++)
        {
            //DataID 地点ID
            sb_Line.Append(ds_line.Tables[0].Rows[i][0].ToString() + "|");
            //DataDesc 地点名称
            sb_Line.Append(ds_line.Tables[0].Rows[i][2].ToString() + "|");

            //GPS 地址坐标(经纬度)(避免多余的“;”出现)
            if (i == ds_line.Tables[0].Rows.Count - 1)
            {
                sb_Line.Append(ds_line.Tables[0].Rows[i][9].ToString());
            }
            else
            {
                sb_Line.Append(ds_line.Tables[0].Rows[i][9].ToString() + ";");
            }

        }
       
        //给string_Line赋值,待前端页面的获取
        string_Line = sb_Line.ToString();

前台脚本文件,获取后台的数据解析后得到位置信息,将其在地图上一一进行展示

<script type="text/javascript">

    // 百度地图API功能
    var map = new BMap.Map("allmap"); // 创建Map实例 allmap 承载百度地图的divID
    map.centerAndZoom(new BMap.Point(113.270793,23.135308), 9); // 初始化地图,设置中心点坐标和地图级别
    map.addControl(new BMap.MapTypeControl()); //添加地图类型控件
    map.setCurrentCity("广州"); // 设置地图显示的城市 此项是必须设置的
    map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放


    //获取后台数据拆分后等待显示
    var bd_String = "<%=string_Line%>";
    var bd_byte = bd_String.split(";");


    //将台区地理点标注到地图上
    for (var i = 0; i < bd_byte.length; i++) {

        var temp = bd_byte[i].split("|");
     
        var label = new BMap.Label(temp[1], { offset: new BMap.Size(20, -10) });
        label.setTitle(temp[0]);

        var position = temp[2].split(",");
  
       addMarker(new BMap.Point(position[0], position[1]), label);
    }


    //创建地图覆盖物和标签
    function addMarker(point, label) {
        var marker = new BMap.Marker(point);
        marker.setLabel(label);
        map.addOverlay(marker);
     
    }

</script>

 嗯,大功告成~

下次呢,我们来总结一下C#后台调用前台JS的函数或者参数的几种方法。祝大家的九月,充实精彩~~~


 

2018-08-21 08:58:51 weixin_42434300 阅读数 7854
  • C# For Unity系列之进阶篇

    整体介绍:       本进阶篇面向的学员不再是完全的编程“小白”,而是具备一定C#编程经验,需要进一步查漏补缺、或者需要进一步全面完善自己C#编程知识体系的广大Unity学员。相信通过本进阶篇的学习,可以使得Unity初中级开发人员对于编程语言的掌握更进一步;对于开发中大型游戏项目,在编程语言这一层级进一步打下坚实的语言基础。 “中级/进阶篇”讲解特点与内容:          本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。         "进阶篇"是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。   C#“进阶篇”教学详细说明如下: 1: IO操作与序列化       学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。 2: 正则表达式       学习正则表达式的强大作用与常用原字符的含义与应用场景。 3: 深入委托与事件       学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。 4: 反射与特性       学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。   5: Linq 查询表达式      学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable<T>) 以及SQL数据库、XML文档方面的强大查询功能。       6: 多线程      学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。      7: Socket套接字通讯      学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。 温习提示:             本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      一、热更新系列(技术含量:中高级): A:《lua热更新技术中级篇》 https://edu.csdn.net/course/detail/27087 B:《热更新框架设计之Xlua基础视频课程》 https://edu.csdn.net/course/detail/27110 C:《热更新框架设计之热更流程与热补丁技术》 https://edu.csdn.net/course/detail/27118 D:《热更新框架设计之客户端热更框架(上)》 https://edu.csdn.net/course/detail/27132 E:《热更新框架设计之客户端热更框架(中)》 https://edu.csdn.net/course/detail/27135 F:《热更新框架设计之客户端热更框架(下)》 https://edu.csdn.net/course/detail/27136 二:框架设计系列(技术含量:中级):  A:《游戏UI界面框架设计系列视频课程》 https://edu.csdn.net/course/detail/27142 B:《Unity客户端框架设计PureMVC篇视频课程(上)》 https://edu.csdn.net/course/detail/27172 C:《Unity客户端框架设计PureMVC篇视频课程(下)》 https://edu.csdn.net/course/detail/27173 D:《AssetBundle框架设计_框架篇视频课程》 https://edu.csdn.net/course/detail/27169 三、Unity脚本从入门到精通(技术含量:初级) A:《C# For Unity系列之入门篇》 https://edu.csdn.net/course/detail/4560 B:《C# For Unity系列之基础篇》 https://edu.csdn.net/course/detail/4595 C: 《C# For Unity系列之中级篇》 https://edu.csdn.net/course/detail/24422 D:《C# For Unity系列之进阶篇》 https://edu.csdn.net/course/detail/24465 四、虚拟现实(VR)与增强现实(AR):(技术含量:初级) A:《虚拟现实之汽车仿真模拟系统 》 https://edu.csdn.net/course/detail/26618 五、Unity基础课程系列(技术含量:初级)  A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》   https://edu.csdn.net/course/detail/24643 B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》 https://edu.csdn.net/course/detail/24645  C:《Unity ECS(二) 小试牛刀》 https://edu.csdn.net/course/detail/27096 六、Unity ARPG课程(技术含量:初中级): A:《MMOARPG地下守护神_单机版实战视频课程(上部)》 https://edu.csdn.net/course/detail/24965 B:《MMOARPG地下守护神_单机版实战视频课程(中部)》 https://edu.csdn.net/course/detail/24968 C:《MMOARPG地下守护神_单机版实战视频课程(下部)》 https://edu.csdn.net/course/detail/24979

    1692 人正在学习 去看看 刘国柱

【1】Web项目中用JS方式调用Cef项目的c#方法:

CEF项目中:
注册C#类为JS对象

browser.RegisterAsyncJsObject("TestJsObject", _thisJsObject, false);


其中:
browser为实例化的ChromiumWebBrowser对象
参数二是被调用的C#类
参数一是c#类对外的名称,
参数三为是否使用驼峰命名法,为false可以在起名时将首字母大写

Web项目中:

<script >
    function GetCef() {
        //cef里注册为JS的C#类【注册的JS名.GetStrThree()为类里的方法名,res为方法的返回值】
        TestJsObject.GetStrThree().then(function(res) {
                alert(res);
            }
        );
    }       
</script>

【2】Cef项目中用使用C#代码调用Web项目中的JS方法:

Web项目中:

<script >
    function DisplayDate() {
       alert("JS方法");

    }
</script>

Cef项目中:

browser.ExecuteScriptAsync("DisplayDate()");


其中
browser为实例化的ChromiumWebBrowser对象
参数为JS方法名

2016-11-11 12:05:36 u010533180 阅读数 5605
  • C# For Unity系列之进阶篇

    整体介绍:       本进阶篇面向的学员不再是完全的编程“小白”,而是具备一定C#编程经验,需要进一步查漏补缺、或者需要进一步全面完善自己C#编程知识体系的广大Unity学员。相信通过本进阶篇的学习,可以使得Unity初中级开发人员对于编程语言的掌握更进一步;对于开发中大型游戏项目,在编程语言这一层级进一步打下坚实的语言基础。 “中级/进阶篇”讲解特点与内容:          本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。         "进阶篇"是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。   C#“进阶篇”教学详细说明如下: 1: IO操作与序列化       学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。 2: 正则表达式       学习正则表达式的强大作用与常用原字符的含义与应用场景。 3: 深入委托与事件       学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。 4: 反射与特性       学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。   5: Linq 查询表达式      学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable<T>) 以及SQL数据库、XML文档方面的强大查询功能。       6: 多线程      学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。      7: Socket套接字通讯      学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。 温习提示:             本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      一、热更新系列(技术含量:中高级): A:《lua热更新技术中级篇》 https://edu.csdn.net/course/detail/27087 B:《热更新框架设计之Xlua基础视频课程》 https://edu.csdn.net/course/detail/27110 C:《热更新框架设计之热更流程与热补丁技术》 https://edu.csdn.net/course/detail/27118 D:《热更新框架设计之客户端热更框架(上)》 https://edu.csdn.net/course/detail/27132 E:《热更新框架设计之客户端热更框架(中)》 https://edu.csdn.net/course/detail/27135 F:《热更新框架设计之客户端热更框架(下)》 https://edu.csdn.net/course/detail/27136 二:框架设计系列(技术含量:中级):  A:《游戏UI界面框架设计系列视频课程》 https://edu.csdn.net/course/detail/27142 B:《Unity客户端框架设计PureMVC篇视频课程(上)》 https://edu.csdn.net/course/detail/27172 C:《Unity客户端框架设计PureMVC篇视频课程(下)》 https://edu.csdn.net/course/detail/27173 D:《AssetBundle框架设计_框架篇视频课程》 https://edu.csdn.net/course/detail/27169 三、Unity脚本从入门到精通(技术含量:初级) A:《C# For Unity系列之入门篇》 https://edu.csdn.net/course/detail/4560 B:《C# For Unity系列之基础篇》 https://edu.csdn.net/course/detail/4595 C: 《C# For Unity系列之中级篇》 https://edu.csdn.net/course/detail/24422 D:《C# For Unity系列之进阶篇》 https://edu.csdn.net/course/detail/24465 四、虚拟现实(VR)与增强现实(AR):(技术含量:初级) A:《虚拟现实之汽车仿真模拟系统 》 https://edu.csdn.net/course/detail/26618 五、Unity基础课程系列(技术含量:初级)  A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》   https://edu.csdn.net/course/detail/24643 B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》 https://edu.csdn.net/course/detail/24645  C:《Unity ECS(二) 小试牛刀》 https://edu.csdn.net/course/detail/27096 六、Unity ARPG课程(技术含量:初中级): A:《MMOARPG地下守护神_单机版实战视频课程(上部)》 https://edu.csdn.net/course/detail/24965 B:《MMOARPG地下守护神_单机版实战视频课程(中部)》 https://edu.csdn.net/course/detail/24968 C:《MMOARPG地下守护神_单机版实战视频课程(下部)》 https://edu.csdn.net/course/detail/24979

    1692 人正在学习 去看看 刘国柱

首先来看一个简单的例子。

       var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                list[i] = () => { Console.WriteLine(i); };
            }
            foreach (var item in list)
            {
                item();
            }

输出结果为:

5
5
5
5
5

通过这个简单的例子,我来简单讲解一下C#中的闭包。
概念:
In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created - i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing.

大概的意思是:从本质上说,闭包是一段可以在晚些时候执行的代码块,但是这段代码块依然维护着它第一个被创建时环境(执行上下文)。 即它仍可以使用创建它的方法中局部变量,即使那个方法已经执行完了。
当然在C#中通常通过匿名函数和Lamada表达式来实现闭包。
经过搜寻,我在msdn的一篇博客中(https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/) 见到了这样一句话:
Because ()=>v means “return the current value of variable v“, not “return the value v was back when the delegate was created”. Closures close over variables, not over values
因为()=> v意味着“返回变量v的当前值”,而不是“返回值v在委托创建时返回”。 闭合变量,而不是值
也就是说 在委托中填入的变量,是最终的那个变量。这样就合理解释了上面为何最终输出的结果都为5。因为i跳出循环时最终的值为5。
接着我们先看一下通过IL,(关于IL指令说明,可以参考这篇文章的最后http://blog.csdn.net/u010533180/article/details/53064257)
反编译出来的代码,建议大家根据上一篇文章画画流程图。

.method private hidebysig static void  ThreadThree() cil managed
{
  // 代码大小       130 (0x82)
  .maxstack  4
  .locals init ([0] class [mscorlib]System.Action[] list,
           [1] class [mscorlib]System.Action 'CS$<>9__CachedAnonymousMethodDelegateb',
           [2] class NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc' 'CS$<>8__localsd',
           [3] class [mscorlib]System.Action item,
           [4] bool CS$4$0000,
           [5] class [mscorlib]System.Action[] CS$6$0001,
           [6] int32 CS$7$0002)
  IL_0000:  nop
  //将整数值 5 作为 int32 推送到计算堆栈上。
  IL_0001:  ldc.i4.5
  //将对新的从零开始的一维数组(其元素属于特定类型)的对象引用推送到计算堆栈上。
  IL_0002:  newarr     [mscorlib]System.Action
  //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。
  IL_0007:  stloc.0
  //  将空引用(O 类型)推送到计算堆栈上。
  IL_0008:  ldnull
  //从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中。
  IL_0009:  stloc.1
  //创建一个值类型的新对象或新实例,并将对象引用(O 类型)推送到计算堆栈上。
  IL_000a:  newobj     instance void NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::.ctor()
  //从计算堆栈的顶部弹出当前值并将其存储到索引 2 处的局部变量列表中。
  IL_000f:  stloc.2
  //将索引 2 处的局部变量加载到计算堆栈上。
  IL_0010:  ldloc.2
  //将整数值 0 作为 int32 推送到计算堆栈上。
  IL_0011:  ldc.i4.0
  //用新值替换在对象引用或指针的字段中存储的值。
  IL_0012:  stfld      int32 NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::i
  //无条件地将控制转移到目标指令(短格式)。等于转移到了IL_0044指令
  IL_0017:  br.s       IL_0044
  IL_0019:  nop
 //将索引 0 处的局部变量加载到计算堆栈上。
  IL_001a:  ldloc.0
  //将索引 2 处的局部变量加载到计算堆栈上。
  IL_001b:  ldloc.2
  //查找对象中其引用当前位于计算堆栈的字段的值。等于查找i的值
  IL_001c:  ldfld      int32 NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::i
  //将索引 1 处的局部变量加载到计算堆栈上。
  IL_0021:  ldloc.1
  //如果 value 为 true、非空或非零,则将控制转移到目标指令(短格式)。 此时判断指令IL_0021的值如果为true ,则跳转到指令IL_0033
    IL_0022:  brtrue.s   IL_0033
 //将索引 2 处的局部变量加载到计算堆栈上。
  IL_0024:  ldloc.2
  //将指向实现特定方法的本机代码的非托管指针(native int 类型)推送到计算堆栈上。
  IL_0025:  ldftn      instance void NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::'<ThreadThree>b__a'()
  //创建一个值类型的新对象或新实例,并将对象引用(O 类型)推送到计算堆栈上。
  IL_002b:  newobj     instance void [mscorlib]System.Action::.ctor(object,
  //从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中。                                                                 native int)
  IL_0030:  stloc.1
  //无条件地将控制转移到目标指令(短格式)。等于转移到了IL_0044指令
  IL_0031:  br.s       IL_0033
 //将索引 1 处的局部变量加载到计算堆栈上。
  IL_0033:  ldloc.1
  //用计算堆栈上的对象 ref 值(O 类型)替换给定索引处的数组元素。这里其实指的就是那个Action类型
  IL_0034:  stelem.ref
  IL_0035:  nop
  //将索引 2 处的局部变量加载到计算堆栈上。
  IL_0036:  ldloc.2
  //复制计算堆栈上当前最顶端的值,然后将副本推送到计算堆栈上。
  IL_0037:  dup
  //查找对象中其引用当前位于计算堆栈的字段的值。等于查找i的值
  IL_0038:  ldfld      int32 NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::i
  将整数值 1 作为 int32 推送到计算堆栈上。
  IL_003d:  ldc.i4.1
  //将两个值相加并将结果推送到计算堆栈上。
  IL_003e:  add
  //用新值替换在对象引用或指针的字段中存储的值。
  IL_003f:  stfld      int32 NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::i
  //将索引 2 处的局部变量加载到计算堆栈上。
  IL_0044:  ldloc.2
  //查找对象中其引用当前位于计算堆栈的字段的值。等于查找i的值
  IL_0045:  ldfld      int32 NowCoderProgrammingProject.ThreadDemo/'<>c__DisplayClassc'::i
   //将索引 0 处的局部变量加载到计算堆栈上。
  IL_004a:  ldloc.0
  //  将从零开始的、一维数组的元素的数目推送到计算堆栈上。
  IL_004b:  ldlen
  //  将位于计算堆栈顶部的值转换为 int32。
  IL_004c:  conv.i4
  //  比较两个值。如果第一个值小于第二个值,则将整数值 1 (int32) 推送到计算堆栈上;反之,将 0 (int32) 推送到计算堆栈上。
  IL_004d:  clt
  //从计算堆栈的顶部弹出当前值并将其存储在局部变量列表中的 index 处(短格式)。
  IL_004f:  stloc.s    CS$4$0000  即 CS$4$0000 这个所在的索引
  //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_0051:  ldloc.s    CS$4$0000
  // 判断此时是否ture,如果为true 则跳转到指令IL_0019
  IL_0053:  brtrue.s   IL_0019
  IL_0055:  nop
  //将索引 0 处的局部变量加载到计算堆栈上。
  IL_0056:  ldloc.0
   //从计算堆栈的顶部弹出当前值并将其存储在局部变量列表中的 index 处(短格式)。
  IL_0057:  stloc.s    CS$6$0001
  //将整数值 0 作为 int32 推送到计算堆栈上。
  IL_0059:  ldc.i4.0
  //从计算堆栈的顶部弹出当前值并将其存储在局部变量列表中的 index 处(短格式)。
  IL_005a:  stloc.s    CS$7$0002
  //  无条件地将控制转移到目标指令(短格式)。 转移到IL_OO73
  IL_005c:  br.s       IL_0073
  //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_005e:  ldloc.s    CS$6$0001
    //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_0060:  ldloc.s    CS$7$0002
  //将位于指定数组索引处的包含对象引用的元素作为 O 类型(对象引用)加载到计算堆栈的顶部。
  IL_0062:  ldelem.ref
  //从计算堆栈的顶部弹出当前值并将其存储到索引 3 处的局部变量列表中。
  IL_0063:  stloc.3
  IL_0064:  nop
  //  将索引 3 处的局部变量加载到计算堆栈上。
  IL_0065:  ldloc.3
  //调用虚方法 执行Action 方法
  IL_0066:  callvirt   instance void [mscorlib]System.Action::Invoke()
  IL_006b:  nop
  IL_006c:  nop
  //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_006d:  ldloc.s    CS$7$0002
    //将整数值 1作为 int32 推送到计算堆栈上。
  IL_006f:  ldc.i4.1
  //将两个值相加并将结果推送到计算堆栈上。
  IL_0070:  add
 //从计算堆栈的顶部弹出当前值并将其存储在局部变量列表中的 index 处(短格式)。
  IL_0071:  stloc.s    CS$7$0002
  //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_0073:  ldloc.s    CS$7$0002
  //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_0075:  ldloc.s    CS$6$0001
  //  将从零开始的、一维数组的元素的数目推送到计算堆栈上。
  IL_0077:  ldlen
   //  将位于计算堆栈顶部的值转换为 int32。
  IL_0078:  conv.i4
  //比较两个值。如果第一个值小于第二个值,则将整数值 1 (int32) 推送到计算堆栈上;反之,将 0 (int32) 推送到计算堆栈上。
  IL_0079:  clt
    //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_007b:  stloc.s    CS$4$0000
    //将特定索引处的局部变量加载到计算堆栈上(短格式)。
  IL_007d:  ldloc.s    CS$4$0000
  //判断此时的值是否为true,如果为true 则跳转到指令IL_005e.这是应该判断数组是否遍历到了末尾
  IL_007f:  brtrue.s   IL_005e
  IL_0081:  ret
} // end of method ThreadDemo::ThreadThree

.NET Reflector 反编译的代码:

 Action[] actionArray = new Action[5];
    Action action = null;
    for (int i = 0; i < actionArray.Length; i++)
    {
        if (action == null)
        {
            action = () => Console.WriteLine(i);
        }
        actionArray[i] = action;
    }
    foreach (Action action2 in actionArray)
    {
        action2();
    }

那么上面的例子,如何输出0-4呢?根据上句话的提示,只需要创建一个变量,保存当前运行状态的值即可。修改后的结果为:

            var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                int localI = i;
                list[i] = () => { Console.WriteLine(localI); };
            }
            foreach (var item in list)
            {
                item();
            }

或者是添加一个额外的方法也行,这样就相当于创建了一个局部变量。代码如下:

     var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                AddList(list, i);
            }
            foreach (var item in list)
            {
                item();
            }
        static void AddList(Action[] list, int i)
        {
            list[i] = () => { Console.WriteLine(i); };
        }

上面两种方法运行输出的结果都为:0-4.

通过上面的分析,加深理解了C#中的闭包,以后要谨慎使用。匿名函数和Lambda表达式给我们的编程带来了许多快捷简单的实现,如(List.Max((a)=>a.Level)等写法)。但是我们要清醒的意识到这两个糖果后面还是有个”坑“(闭包)。这再次告诉我们技术工作人,要”知其然,也要知其所以然“。

下面给出完整的代码,其中有一些是我自己研究的,上面没有给出分析,建议读者自己分析,加深理解:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NowCoderProgrammingProject
{
    class ThreadDemo
    {
        public static void Main()
        {
            ThreadOne();
            ThreadOne2();
            ThreadTwo();
            ThreadThree();
            ThreadThree1();
        }

        private static void ThreadOne()
        {
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(() =>
                {
                    Console.WriteLine(string.Format("{0}:{1}", Thread.CurrentThread.Name, i));
                });
                t.Name = string.Format("Thread{0}", i);
                t.IsBackground = true;
                t.Start();
            }
            Console.ReadLine();
        }

        private static void ThreadOne2()
        {
            for (int i = 0; i < 10; i++)
            {
                int localId = i;
                Thread t = new Thread(() =>
                {
                    Console.WriteLine(string.Format("{0}:{1}", Thread.CurrentThread.Name, localId));
                });
                t.Name = string.Format("Thread{0}", i);
                t.IsBackground = true;
                t.Start();
            }
            Console.ReadLine();
        }

        private static void ThreadTwo()
        {
            int id = 0;
            for (int i = 0; i < 10; i++)
            {
                NewMethod(i, id++);
            }
            Console.ReadLine();
        }

        private static void NewMethod(int i, int readTimeID)
        {
            Thread t = new Thread(() =>
            {
                Console.WriteLine(string.Format("{0}:{1}", Thread.CurrentThread.Name, readTimeID));
            });
            t.Name = string.Format("Thread{0}", i);
            t.IsBackground = true;
            t.Start();
        }

        static void ThreadThree()
        {
            var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                list[i] = () => { Console.WriteLine(i); };
            }
            foreach (var item in list)
            {
                item();
            }
        }
        static void ThreadThree1()
        {
            var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                int localI = i;
                list[i] = () => { Console.WriteLine(localI); };
            }
            foreach (var item in list)
            {
                item();
            }
        }
        static void ThreadThree2()
        {
            var list = new Action[5];
            for (int i = 0; i < list.Length; i++)
            {
                AddList(list, i);
            }
            foreach (var item in list)
            {
                item();
            }
        }
        static void AddList(Action[] list, int i)
        {
            list[i] = () => { Console.WriteLine(i); };
        }
    }
}

参考文章:
https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/

https://blogs.msdn.microsoft.com/ericlippert/2009/11/16/closing-over-the-loop-variable-part-two/

为了防止上面的文章失效,下面一篇博客进行对其翻译。

没有更多推荐了,返回首页