VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#教程之 C#线程安全类型(2)

"Processor " + i; processors[i - 1] = Task.Run( () => TaskProcessor(taskCollection, processorId)); } await taskSource; await Task.WhenAll(processors); } /// <summary> /// 初始化collection中的数据 /// </summary> /// <param name="collection"></param> /// <returns></returns> static async Task TaskProducer(BlockingCollection<CustomTask> collection) { for (int i = 1; i <= 20; i++) { await Task.Delay(20); var workItem = new CustomTask { Id = i }; collection.Add(workItem); Console.WriteLine("Task {0} has been posted", workItem.Id); } collection.CompleteAdding(); } /// <summary> /// 打印collection中的数据 /// </summary> /// <param name="collection"></param> /// <param name="name"></param> /// <returns></returns> static async Task TaskProcessor( BlockingCollection<CustomTask> collection, string name) { await Module.GetRandomDelay(); foreach (CustomTask item in collection.GetConsumingEnumerable()) { Console.WriteLine("Task {0} has been processed by {1}", item.Id, name); await Module.GetRandomDelay(); } } } }
复制代码

7、使用ThreadStatic特性
  ThreadStatic特性是最简单的TLS使用,且只支持静态字段,只需要在字段上标记这个特性就可以了

复制代码
using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        //TLS中的str变量
        //可以看到,str静态字段在两个线程中都是独立存储的,互相不会被修改。
        [ThreadStatic]
        static string str = "hehe";

        static void Main(string[] args)
        {
            //另一个线程只会修改自己TLS中的hehe
            Thread th = new Thread(() => { str = "Mgen"; Display(); });
            th.Start();
            th.Join();
            Display();
        }
        static void Display()
        {
            Console.WriteLine("{0} {1}", Thread.CurrentThread.ManagedThreadId, str);
        }

    }
}
复制代码

8、使用命名的LocalDataStoreSlot类型
  显然ThreadStatic特性只支持静态字段太受限制了。.NET线程类型中的LocalDataStoreSlot提供更好的TLS支持。我们先来看看命名的LocalDataStoreSlot类型,可以通过Thread.AllocateNamedDataSlot来分配一个命名的空间,通过Thread.FreeNamedDataSlot来销毁一个命名的空间。空间数据的获取和设置则通过Thread类型的GetData方法和SetData方法。

复制代码
using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建Slot
            LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot("slot");

            //设置TLS中的值
            Thread.SetData(slot, "hehe");

            //修改TLS的线程
            Thread th = new Thread(() =>
            {
                Thread.SetData(slot, "Mgen");
                Display();
            });

            th.Start();
            th.Join();
            Display();

            //清除Slot
            Thread.FreeNamedDataSlot("slot");
        }

        //显示TLS中Slot值
        static void Display()
        {
            LocalDataStoreSlot dataslot = Thread.GetNamedDataSlot("slot");
            Console.WriteLine("{0} {1}", Thread.CurrentThread.ManagedThreadId, Thread.GetData(dataslot));
        }

    }
}
复制代码

9、使用未命名的LocalDataStoreSlot类型
  线程同样支持未命名的LocalDataStoreSlot,未命名的LocalDataStoreSlot不需要手动清除,分配则需要Thread.AllocateDataSlot方法。注意由于未命名的LocalDataStoreSlot没有名称,因此无法使用Thread.GetNamedDataSlot方法,只能在多个线程中引用同一个LocalDataStoreSlot才可以对TLS空间进行操作,将上面的命名的LocalDataStoreSlot代码改成未命名的LocalDataStoreSlot执行

复制代码
using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        //静态LocalDataStoreSlot变量
        static LocalDataStoreSlot slot;

        static void Main(string[] args)
        {
            //创建Slot
            slot = Thread.AllocateDataSlot();

            //设置TLS中的值
            Thread.SetData(slot, "hehe");

            //修改TLS的线程
            Thread th = new Thread(() =>
            {
                Thread.SetData(slot, "Mgen");
                Display();

            });

            th.Start();
            th.Join();
            Display();
        }

        //显示TLS中Slot值
        static void Display()
        {
            Console.WriteLine("{0} {1}", Thread.CurrentThread.ManagedThreadId, Thread.GetData(slot));
        }

    }
}
复制代码

10、使用.NET 4.0的ThreadLocal<T>类型
  .NET 4.0在线程方面加入了很多东西,其中就包括ThreadLocal<T>类型,他的出现更大的简化了TLS的操作。ThreadLocal<T>类型和Lazy<T>惊人相似,构造函数参数是Func<T>用来创建对象(当然也可以理解成对象的默认值),然后用Value属性来得到或者设置这个对象。
  ThreadLocal的操作或多或少有点像上面的未命名的LocalDataStoreSlot,但ThreadLocal感觉更简洁更好理解。

复制代码
using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static ThreadLocal<string> local;

        static void Main(string[] args)
        {
            //创建ThreadLocal并提供默认值
            local = new ThreadLocal<string>(() => "hehe");

            //修改TLS的线程
            Thread th = new Thread(() =>
            {

                local.Value = "Mgen";
                Display();
            });

            th.Start();
            th.Join();
            Display();
        }

        //显示TLS中数据值
        static void Display()
        {
            Console.WriteLine("{0} {1}", Thread.CurrentThread.ManagedThreadId, local.Value);
        }

    }
}
复制代码


相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号