The foreach identifier and closures

前端 未结 7 1463
误落风尘
误落风尘 2020-11-22 10:51

In the two following snippets, is the first one safe or must you do the second one?

By safe I mean is each thread guaranteed to call the method on the Foo from the s

7条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-22 11:04

    This is an interesting question and it seems like we have seen people answer in all various ways. I was under the impression that the second way would be the only safe way. I whipped a real quick proof:

    class Foo
    {
        private int _id;
        public Foo(int id)
        {
            _id = id;
        }
        public void DoSomething()
        {
            Console.WriteLine(string.Format("Thread: {0} Id: {1}", Thread.CurrentThread.ManagedThreadId, this._id));
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var ListOfFoo = new List();
            ListOfFoo.Add(new Foo(1));
            ListOfFoo.Add(new Foo(2));
            ListOfFoo.Add(new Foo(3));
            ListOfFoo.Add(new Foo(4));
    
    
            var threads = new List();
            foreach (Foo f in ListOfFoo)
            {
                Thread thread = new Thread(() => f.DoSomething());
                threads.Add(thread);
                thread.Start();
            }
        }
    }
    

    if you run this you will see option 1 is definetly not safe.

提交回复
热议问题