来自 澳门新葡亰 2019-11-10 06:25 的文章
当前位置: 澳门新葡亰app > 澳门新葡亰 > 正文

澳门新葡亰官网APP:线程相关的静态字段和数据

1、IProducerConsumerCollection (线程安全接口)
  此接口的享有完结必得都启用此接口的具备成员,若要从八个线程同一时间采纳。

Thread Local Storage: Thread-Relative Static Fields and Data Slots



文章摘自msdn library官方文书档案

可以动用托管线程本地存款和储蓄区 (TLS) 存款和储蓄某一线程和应用程序域所独有的数额。 .NET Framework 提供了三种选择托管 TLS 的主意:线程相关的静态字段和数据槽。

  • 假如你能够在编写翻译时预料到您的适当必要,请使用线程相关的静态字段(在 Visual Basic 中为线程相关的 Shared 字段卡塔 尔(阿拉伯语:قطر‎。 线程相关的静态字段可提供最好质量。 它们还兼具编写翻译时类型检查的长处。

  • 假使一定要在运营时意识你的莫过于需求,请使用数据槽。 数据槽比线程相关的静态字段慢一些且更为劳累使用,並且数据存款和储蓄为 Object.aspx) 类型,因此必须将其挟持调换为正确的类型本事使用。

在非托管 C++ 中,能够选取 TlsAlloc 来动态分配槽,使用 __declspec(thread) 来注解变量应在线程相关的存款和储蓄区中开展分配。 线程相关的静态字段和数据槽提供了此作为的托管版本。

在 .NET Framework 4中,能够接纳 System.Threading.ThreadLocal<T>.aspx) 类成立线程本地对象,在率先次利用该对象时它将惰式初叶化。 有关详细新闻,请参阅延迟开端化.aspx)。

托管 TLS 中数据的唯生龙活虎性

 

随意使用线程相关的静态字段依旧采纳数据槽,托管 TLS 中的数据都以线程和选用程序域组合所独有的。

  • 在动用程序域内部,一个线程无法校正另二个线程中的数据,纵然那四个线程使用同多少个字段或槽时也不可能。

  • 当线程从三个应用程序域中拜会同三个字段或槽时,会在各种应用程序域中有限匡助叁个独自的值。

举例说,假使有个别线程设置线程相关的静态字段的值,接着它步入另二个用到程序域,然后搜索该字段的值,则在第三个利用程序域中搜寻的值将分裂于第二个使用程序域中的值。 在其次个利用程序域中为该字段设置三个新值不会潜濡默化率先个应用程序域中该字段的值。

同等,当某些线程获取几个例外应用程序域中的同一命名数据槽时,第一个应用程序域中的数据将始终与第三个使用程序域中的数据非亲非故。

线程相关的静态字段

 

倘令你知道有个别数据连接有些线程和动用程序域组合所只有的,请向该静态字段应用 ThreadStaticAttribute.aspx) 本性。 与行使任何其余静态字段同样选拔该字段。 该字段中的数据是各样使用它的线程所唯有的。

线程相关的静态字段的性质优于数据槽,并且具备编写翻译时类型检查的独特之处。

请小心,任何类构造函数代码都将要拜望该字段的率先个上下文中的第五个线程上运维。 在同等应用程序域内的享有别的线程或左右文中,假如字段是援用类型,它们将被开端化为 null(在 Visual Basic 中为 Nothing卡塔 尔(阿拉伯语:قطر‎;假若字段是值类型,它们将被先河化为它们的暗中同意值。 由此,您不应信任于类构造函数来开端化线程相关的静态字段。 而应防止开始化线程相关的静态字段并假定它们先河化为 null (Nothing) 或它们的默许值。

数据槽

 

.NET Framework 提供了线程和接受程序域组合所独有的动态数据槽。 数据槽饱含三种档次:命名槽和未命名槽。 两个都是由此选取LocalDataStoreSlot.aspx) 结构来促成的。

  • 若要创造命名数据槽,请使用 Thread.AllocateNamedDataSlot.aspx) 或 Thread.GetNamedDataSlot.aspx) 方法。 若要赢得对某些现存命名槽的引用,请将其名称传递给 GetNamedDataSlot.aspx) 方法。

  • 若要创建未命名数据槽,请使用 Thread.AllocateDataSlot.aspx) 方法。

对此命名槽和未命名槽,请使用 Thread.SetData.aspx) 和 Thread.GetData.aspx) 方法设置和检索槽中的音信。 这么些都是静态方法,它们一向成效于如今正在施行它们的线程的数量。

命名槽恐怕很平价,因为你可以在急需它时经过将其名称传递给 GetNamedDataSlot.aspx) 方法来搜寻该槽,并非保卫安全对未命名槽的援用。 不过,假使另三个组件使用同少年老成的名号来定名其线程相关的存款和储蓄区,况且有三个线程同期实行来自您的机件和该器件的代码,则那七个构件只怕会毁掉相互的数目。(本方案黄金年代经这多少个零器件在一直以来应用程序域内运行,何况它们并不用于分享雷同数量。卡塔尔

澳门新葡亰官网APP 1澳门新葡亰官网APP 2

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace ConsoleApp1
{
    public class SafeStack<T> : IProducerConsumerCollection<T>
    {
        // Used for enforcing thread-safety
        private object m_lockObject = new object();

        // We'll use a regular old Stack for our core operations
        private Stack<T> m_sequentialStack = null;

        //
        // Constructors
        //
        public SafeStack()
        {
            m_sequentialStack = new Stack<T>();
        }

        public SafeStack(IEnumerable<T> collection)
        {
            m_sequentialStack = new Stack<T>(collection);
        }

        //
        // Safe Push/Pop support
        //
        public void Push(T item)
        {
            lock (m_lockObject) m_sequentialStack.Push(item);
        }

        public bool TryPop(out T item)
        {
            bool rval = true;
            lock (m_lockObject)
            {
                if (m_sequentialStack.Count == 0) { item = default(T); rval = false; }
                else item = m_sequentialStack.Pop();
            }
            return rval;
        }

        //
        // IProducerConsumerCollection(T) support
        //
        public bool TryTake(out T item)
        {
            return TryPop(out item);
        }

        public bool TryAdd(T item)
        {
            Push(item);
            return true; // Push doesn't fail
        }

        public T[] ToArray()
        {
            T[] rval = null;
            lock (m_lockObject) rval = m_sequentialStack.ToArray();
            return rval;
        }

        public void CopyTo(T[] array, int index)
        {
            lock (m_lockObject) m_sequentialStack.CopyTo(array, index);
        }



        //
        // Support for IEnumerable(T)
        //
        public IEnumerator<T> GetEnumerator()
        {
            // The performance here will be unfortunate for large stacks,
            // but thread-safety is effectively implemented.
            Stack<T> stackCopy = null;
            lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack);
            return stackCopy.GetEnumerator();
        }


        //
        // Support for IEnumerable
        //
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<T>)this).GetEnumerator();
        }

        // 
        // Support for ICollection
        //
        public bool IsSynchronized
        {
            get { return true; }
        }

        public object SyncRoot
        {
            get { return m_lockObject; }
        }

        public int Count
        {
            get { return m_sequentialStack.Count; }
        }

        public void CopyTo(Array array, int index)
        {
            lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index);
        }
    }
}

SafeStack

澳门新葡亰官网APP 3澳门新葡亰官网APP 4

using System;
using System.Collections.Concurrent;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            TestSafeStack();

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }

        // Test our implementation of IProducerConsumerCollection(T)
        // Demonstrates:
        //      IPCC(T).TryAdd()
        //      IPCC(T).TryTake()
        //      IPCC(T).CopyTo()
        static void TestSafeStack()
        {
            SafeStack<int> stack = new SafeStack<int>();
            IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack;

            // Test Push()/TryAdd()
            stack.Push(10); Console.WriteLine("Pushed 10");
            ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20");
            stack.Push(15); Console.WriteLine("Pushed 15");

            int[] testArray = new int[3];

            // Try CopyTo() within boundaries
            try
            {
                ipcc.CopyTo(testArray, 0);
                Console.WriteLine("CopyTo() within boundaries worked, as expected");
            }
            catch (Exception e)
            {
                Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message);
            }

            // Try CopyTo() that overflows
            try
            {
                ipcc.CopyTo(testArray, 1);
                Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE");
            }
            catch (Exception e)
            {
                Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message);
            }

            // Test enumeration
            Console.Write("Enumeration (should be three items): ");
            foreach (int item in stack)
                Console.Write("{0} ", item);
            Console.WriteLine("");

            // Test TryPop()
            int popped = 0;
            if (stack.TryPop(out popped))
            {
                Console.WriteLine("Successfully popped {0}", popped);
            }
            else Console.WriteLine("FAILED to pop!!");

            // Test Count
            Console.WriteLine("stack count is {0}, should be 2", stack.Count);

            // Test TryTake()
            if (ipcc.TryTake(out popped))
            {
                Console.WriteLine("Successfully IPCC-TryTaked {0}", popped);
            }
            else Console.WriteLine("FAILED to IPCC.TryTake!!");
        }
    }
}

Program

2、ConcurrentStack类:安全货仓

澳门新葡亰官网APP 5澳门新葡亰官网APP 6

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Task t = RunProgram();
            t.Wait();
        }

        static async Task RunProgram()
        {
            var taskStack = new ConcurrentStack<CustomTask>();
            var cts = new CancellationTokenSource();

            var taskSource = Task.Run(() => TaskProducer(taskStack));

            Task[] processors = new Task[4];
            for (int i = 1; i <= 4; i++)
            {
                string processorId = i.ToString();
                processors[i - 1] = Task.Run(
                    () => TaskProcessor(taskStack, "Processor " + processorId, cts.Token));
            }

            await taskSource;
            cts.CancelAfter(TimeSpan.FromSeconds(2));

            await Task.WhenAll(processors);
        }

        static async Task TaskProducer(ConcurrentStack<CustomTask> stack)
        {
            for (int i = 1; i <= 20; i++)
            {
                await Task.Delay(50);
                var workItem = new CustomTask { Id = i };
                stack.Push(workItem);
                Console.WriteLine("Task {0} has been posted", workItem.Id);
            }
        }

        static async Task TaskProcessor(
            ConcurrentStack<CustomTask> stack, string name, CancellationToken token)
        {
            await GetRandomDelay();
            do
            {
                CustomTask workItem;
                bool popSuccesful = stack.TryPop(out workItem);
                if (popSuccesful)
                {
                    Console.WriteLine("Task {0} has been processed by {1}", workItem.Id, name);
                }

                await GetRandomDelay();
            }
            while (!token.IsCancellationRequested);
        }

        static Task GetRandomDelay()
        {
            int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
            return Task.Delay(delay);
        }

        class CustomTask
        {
            public int Id { get; set; }
        }
    }
}

Program

3、ConcurrentQueue类:安全队列

澳门新葡亰官网APP 7澳门新葡亰官网APP 8

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Task t = RunProgram();
            t.Wait();
        }

        static async Task RunProgram()
        {
            var taskQueue = new ConcurrentQueue<CustomTask>();
            var cts = new CancellationTokenSource();

            var taskSource = Task.Run(() => TaskProducer(taskQueue));

            Task[] processors = new Task[4];
            for (int i = 1; i <= 4; i++)
            {
                string processorId = i.ToString();
                processors[i - 1] = Task.Run(
                    () => TaskProcessor(taskQueue, "Processor " + processorId, cts.Token));
            }

            await taskSource;
            cts.CancelAfter(TimeSpan.FromSeconds(2));

            await Task.WhenAll(processors);
        }

        static async Task TaskProducer(ConcurrentQueue<CustomTask> queue)
        {
            for (int i = 1; i <= 20; i++)
            {
                await Task.Delay(50);
                var workItem = new CustomTask { Id = i };
                queue.Enqueue(workItem);
                Console.WriteLine("插入Task {0} has been posted ThreadID={1}", workItem.Id, Thread.CurrentThread.ManagedThreadId);
            }
        }

        static async Task TaskProcessor(
            ConcurrentQueue<CustomTask> queue, string name, CancellationToken token)
        {
            CustomTask workItem;
            bool dequeueSuccesful = false;

            await GetRandomDelay();
            do
            {
                dequeueSuccesful = queue.TryDequeue(out workItem);
                if (dequeueSuccesful)
                {
                    Console.WriteLine("读取Task {0} has been processed by {1} ThreadID={2}",
                                        workItem.Id, name, Thread.CurrentThread.ManagedThreadId);
                }

                await GetRandomDelay();
            }
            while (!token.IsCancellationRequested);
        }

        static Task GetRandomDelay()
        {
            int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
            return Task.Delay(delay);
        }

        class CustomTask
        {
            public int Id { get; set; }
        }
    }
}

Program

4、ConcurrentDictionary类
  ConcurrentDictionary类写操作比使用锁的经常字典(Dictionary)要慢的多,而读操作则要快些。因而对字典要豁达的线程安全的读操作,ConcurrentDictionary类是最佳的选取
  ConcurrentDictionary类的贯彻利用了细粒度锁(fine-grained locking)技能,这在三多线程写入方面比接纳锁的平日的字典(也被誉为粗粒度锁)

澳门新葡亰官网APP 9澳门新葡亰官网APP 10

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var concurrentDictionary = new ConcurrentDictionary<int, string>();
            var dictionary = new Dictionary<int, string>();

            var sw = new Stopwatch();

            sw.Start();
            for (int i = 0; i < 1000000; i++)
            {
                lock (dictionary)
                {
                    dictionary[i] = Item;
                }
            }
            sw.Stop();
            Console.WriteLine("Writing to dictionary with a lock: {0}", sw.Elapsed);

            sw.Restart();
            for (int i = 0; i < 1000000; i++)
            {
                concurrentDictionary[i] = Item;
            }
            sw.Stop();
            Console.WriteLine("Writing to a concurrent dictionary: {0}", sw.Elapsed);

            sw.Restart();
            for (int i = 0; i < 1000000; i++)
            {
                lock (dictionary)
                {
                    CurrentItem = dictionary[i];
                }
            }
            sw.Stop();
            Console.WriteLine("Reading from dictionary with a lock: {0}", sw.Elapsed);

            sw.Restart();
            for (int i = 0; i < 1000000; i++)
            {
                CurrentItem = concurrentDictionary[i];
            }
            sw.Stop();
            Console.WriteLine("Reading from a concurrent dictionary: {0}", sw.Elapsed);
        }

        const string Item = "Dictionary item";
        public static string CurrentItem;
    }
}

Program

5、ConcurrentBag类

澳门新葡亰官网APP 11澳门新葡亰官网APP 12

namespace ConsoleApp1
{
    class CrawlingTask
    {
        public string UrlToCrawl { get; set; }

        public string ProducerName { get; set; }
    }
}

CrawlingTask

澳门新葡亰官网APP 13澳门新葡亰官网APP 14

using System.Collections.Generic;

namespace ConsoleApp1
{
    static class Module
    {
        public static Dictionary<string, string[]> _contentEmulation = new Dictionary<string, string[]>();

        public static void CreateLinks()
        {
            _contentEmulation["http://microsoft.com/"] = new[] { "http://microsoft.com/a.html", "http://microsoft.com/b.html" };
            _contentEmulation["http://microsoft.com/a.html"] = new[] { "http://microsoft.com/c.html", "http://microsoft.com/d.html" };
            _contentEmulation["http://microsoft.com/b.html"] = new[] { "http://microsoft.com/e.html" };

            _contentEmulation["http://google.com/"] = new[] { "http://google.com/a.html", "http://google.com/b.html" };
            _contentEmulation["http://google.com/a.html"] = new[] { "http://google.com/c.html", "http://google.com/d.html" };
            _contentEmulation["http://google.com/b.html"] = new[] { "http://google.com/e.html", "http://google.com/f.html" };
            _contentEmulation["http://google.com/c.html"] = new[] { "http://google.com/h.html", "http://google.com/i.html" };

            _contentEmulation["http://facebook.com/"] = new[] { "http://facebook.com/a.html", "http://facebook.com/b.html" };
            _contentEmulation["http://facebook.com/a.html"] = new[] { "http://facebook.com/c.html", "http://facebook.com/d.html" };
            _contentEmulation["http://facebook.com/b.html"] = new[] { "http://facebook.com/e.html" };

            _contentEmulation["http://twitter.com/"] = new[] { "http://twitter.com/a.html", "http://twitter.com/b.html" };
            _contentEmulation["http://twitter.com/a.html"] = new[] { "http://twitter.com/c.html", "http://twitter.com/d.html" };
            _contentEmulation["http://twitter.com/b.html"] = new[] { "http://twitter.com/e.html" };
            _contentEmulation["http://twitter.com/c.html"] = new[] { "http://twitter.com/f.html", "http://twitter.com/g.html" };
            _contentEmulation["http://twitter.com/d.html"] = new[] { "http://twitter.com/h.html" };
            _contentEmulation["http://twitter.com/e.html"] = new[] { "http://twitter.com/i.html" };
        }
    }
}

Module

澳门新葡亰官网APP 15澳门新葡亰官网APP 16

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Module.CreateLinks();
            Task t = RunProgram();
            t.Wait();
        }

        static async Task RunProgram()
        {
            var bag = new ConcurrentBag<CrawlingTask>();

            string[] urls = new[] { "http://microsoft.com/", "http://google.com/", "http://facebook.com/", "http://twitter.com/" };

            var crawlers = new Task[4];
            for (int i = 1; i <= 4; i++)
            {
                string crawlerName = "Crawler " + i.ToString();
                bag.Add(new CrawlingTask { UrlToCrawl = urls[i - 1], ProducerName = "root" });
                crawlers[i - 1] = Task.Run(() => Crawl(bag, crawlerName));
            }

            await Task.WhenAll(crawlers);
        }

        static async Task Crawl(ConcurrentBag<CrawlingTask> bag, string crawlerName)
        {
            CrawlingTask task;
            //尝试从bag中取出对象
            while (bag.TryTake(out task))
            {
                IEnumerable<string> urls = await GetLinksFromContent(task);
                if (urls != null)
                {
                    foreach (var url in urls)
                    {
                        var t = new CrawlingTask
                        {
                            UrlToCrawl = url,
                            ProducerName = crawlerName
                        };
                        //将子集插入到bag中 
                        bag.Add(t);
                    }
                }
                Console.WriteLine("Indexing url {0} posted by {1} is completed by {2}!",
                    task.UrlToCrawl, task.ProducerName, crawlerName);
            }
        }

        static async Task<IEnumerable<string>> GetLinksFromContent(CrawlingTask task)
        {
            await GetRandomDelay();

            if (Module._contentEmulation.ContainsKey(task.UrlToCrawl)) return Module._contentEmulation[task.UrlToCrawl];

            return null;
        }

        static Task GetRandomDelay()
        {
            int delay = new Random(DateTime.Now.Millisecond).Next(150, 200);
            return Task.Delay(delay);
        }


    }
}

Program

6、BlockingCollection类
  BlockingCollection类: 大家能够改变职务存款和储蓄在窒碍会集中的情势。暗许景况下它应用的是ConcurrentQueue容器,可是我们能够运用任何完成了IProducerConsumerCollection泛型接口的集合。

澳门新葡亰官网APP 17澳门新葡亰官网APP 18

namespace ConsoleApp1
{
    class CustomTask
    {
        public int Id { get; set; }
    }
}

CustomTask

澳门新葡亰官网APP 19澳门新葡亰官网APP 20

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    static class Module
    {
        public static Task GetRandomDelay()
        {
            int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
            return Task.Delay(delay);
        }
    }
}

Module

澳门新葡亰官网APP 21澳门新葡亰官网APP 22

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Using a Queue inside of BlockingCollection");
            Console.WriteLine();
            Task t = RunProgram();
            t.Wait();

            //Console.WriteLine();
            //Console.WriteLine("Using a Stack inside of BlockingCollection");
            //Console.WriteLine();
            //Task t = RunProgram(new ConcurrentStack<CustomTask>());
            //t.Wait();
        }

        static async Task RunProgram(IProducerConsumerCollection<CustomTask> collection = null)
        {
            var taskCollection = new BlockingCollection<CustomTask>();
            if (collection != null)
                taskCollection = new BlockingCollection<CustomTask>(collection);
            //初始化collection中的数据
            var taskSource = Task.Run(() => TaskProducer(taskCollection));

            Task[] processors = new Task[4];
            for (int i = 1; i <= 4; i++)
            {
                string processorId = "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();
            }
        }
    }
}

Program

7、使用ThreadStatic特性
  ThreadStatic本性是最简易的TLS使用,且只帮助静态字段,只须要在字段上标志那几个特点就能够了

澳门新葡亰官网APP 23澳门新葡亰官网APP 24

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);
        }

    }
}

Program

8、使用命名的LocalDataStoreSlot类型
  明显ThreadStatic天性只帮助静态字段太受约束了。.NET线程类型中的LocalDataStoreSlot提供更加好的TLS协助。大家先来看看命名的LocalDataStoreSlot类型,能够通过Thread.AllocateNamedDataSlot来分配三个命名的空间,通过Thread.FreeNamedDataSlot来销毁一个命名的上空。空间数据的得到和装置则经过Thread类型的GetData方法和SetData方法。

澳门新葡亰官网APP 25澳门新葡亰官网APP 26

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));
        }

    }
}

Program

9、使用未命名的LocalDataStoreSlot类型
  线程相通协助未命名的LocalDataStoreSlot,未命名的LocalDataStoreSlot无需手动解除,分配则供给Thread.AllocateDataSlot方法。注意由于未命名的LocalDataStoreSlot未有称谓,由此不也许选用Thread.GetNamedDataSlot方法,只好在三个线程中引用同八个LocalDataStoreSlot才得以对TLS空间拓宽操作,将下面的命名的LocalDataStoreSlot代码改成未命名的LocalDataStoreSlot实施

澳门新葡亰官网APP 27澳门新葡亰官网APP 28

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));
        }

    }
}

Program

10、使用.NET 4.0的ThreadLocal<T>类型
  .NET 4.0在线程方面出席了累累东西,在那之中就总结ThreadLocal<T>类型,他的面世更加大的简化了TLS的操作。ThreadLocal<T>类型和Lazy<T>惊人相仿,构造函数参数是Func<T>用来创设对象(当然也能够掌握成靶子的默许值卡塔 尔(阿拉伯语:قطر‎,然后用Value属性来获得可能设置那些目的。
  ThreadLocal的操作或多或少有一点点像上边的未命名的LocalDataStoreSlot,但ThreadLocal感觉越来越精短越来越好驾驭。

澳门新葡亰官网APP 29澳门新葡亰官网APP 30

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);
        }

    }
}

Program

 

本文由澳门新葡亰app发布于澳门新葡亰,转载请注明出处:澳门新葡亰官网APP:线程相关的静态字段和数据

关键词: