警惕匿名方法造成的变量共享

来源:网络 责任编辑:栏目编辑 发表时间:2013-07-01 15:05 点击:

 

匿名方法

匿名方法是.NET 2.0中引入的高级特性,“匿名”二字说明它可以把实现内联地写在一个方法中,从而形成一个委托对象,而不用有明确地方法名,例如:

static void Test()

{

    Action<string> action = delegate(string value)

    {

        Console.WriteLine(value);

    };

 

    action("Hello World");

}

但是匿名方法的关键并不仅于“匿名”二字。其最强大的特性就在于匿名方法形成了一个闭包,它可以作为参数传递到另一个方法中去,但同时也能访问方法的局部变量和当前类中的其它成员。例如:

class TestClass

{

    private void Print(string message)

    {

        Console.WriteLine(message);

    }

 

    public void Test()

    {

        string[] messages = new string[] { "Hello", "World" };

        int index = 0;

 

        Action<string> action = (m) =>

        {

            this.Print((index++) + ". " + m);

        };

 

        Array.ForEach(messages, action);

        Console.WriteLine("index = " + index);

    }

}

如上所示,在TestClass的Test方法中,action委托调用了同在TestClass类中的私有方法Print,并对Test方法中的局部变量index进行了读写。在加上C# 3.0中Lambda表达式的新特性,匿名方法的使用得到了极大的推广。不过,如果使用不当,匿名方法也容易造成难以发现的问题。

问题案例

某位兄弟最近在一个简单的数据导入程序,主要工作是从文本文件中读取数据,进行分析和重组,然后写入数据库。其逻辑大致如下:

static void Process()

{

    List<Item> batchItems = new List<Item>();

    foreach (var item in ...)

    {

        batchItems.Add(item);

 

        if (batchItems.Count > 1000)

        {

            DataContext db = new DataContext();

            db.Items.InsertAllOnSubmit(batchItems);

            db.SubmitChanges();

 

            batchItems = new List<Item>();

        }

    }

}

每次从数据源中读取数据后,添加到batchItems列表中,当batchItems满1000条时便进行一次提交。这段代码功能运行正常,可惜时间卡在了数据库提交上。数据的获取和处理很快,但是提交一次就要花较长时间。于是想想,数据提交和数据处理不会有资源上的冲突,那么就把数据提交放在另外一个线程上进行处理吧!于是,使用ThreadPool来改写代码:

static void Process()

{

    List<Item> batchItems = new List<Item>();

    foreach (var item in ...)

    {

        batchItems.Add(item);

 

        if (batchItems.Count > 1000)

        {

            ThreadPool.QueueUserWorkItem((o) =>

    相关新闻>>

      发表评论
      请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
      用户名: 验证码:点击我更换图片
      最新评论 更多>>

      推荐热点

      • 浅析.NET下XML数据访问新机制
      • asp.net 面试+笔试题目第1/2页
      • C# 邮件地址是否合法的验证
      • C#高级编程:数据库连接[1]
      • asp.net 设置GridView的选中行的实现代码
      • 经典C++程序1
      • IIS 自动回收导致后台定时器失效的问题解决
      • ASP.NET&#160;GridView列表代码示例
      • 微软ASP.NET站点部署指南(3):使用Web.Config文件的Transforma
      网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
      Copyright © 2008-2015 计算机技术学习交流网. 版权所有

      豫ICP备11007008号-1