为什么有" null"在c#?

时间:2016-01-05 09:49:59

标签: c#

我想在C#中模拟生产者Consumer。一个线程作为生成器,新的数组对象,并将该数组放入List.Another线程作为comsumer工作,当List中有元素时,它得到数组并做一些东西。代码在这里。为什么在这个过程中有" null" s。怎么解决? 调用list.add(tmp)时mybe引起的问题,在ushort [] tmp准备好之前添加了一个list.Count。任何人都可以解释这个过程的机制。

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

    namespace listTest
    {
        class Program
        {
            static List<ushort[]> list = new List<ushort[]>();
            static void func1()
            {
                while (true)
                {
                    ushort[] tmp;
                    while (true)
                    {
                        tmp = new ushort[100];
                        if (tmp != null)
                            break;
                    }


                    list.Add(tmp);
                    Thread.Sleep(10);
                }
            }
            static void func2()
            {
                while (true)
                {
                    if (list.Count > 0)
                    {
                        ushort[] data = list.ElementAt(0);
                        if (data == null)
                            Console.Write("null\n");
                        else
                        {
                            for (int i = 0; i < data.Length; i++)
                            {
                                data[i] += 1;
                            }
                        }
                        Console.Write("ok ");
                        list.RemoveAt(0);
                    }

                }
            }


            static void Main(string[] args)
            {
                Thread func1T = new Thread(func1);
                Thread func2T = new Thread(func2);
                func1T.Start();
                func2T.Start();
            }

        }
    }

1 个答案:

答案 0 :(得分:1)

您有时会获得null的问题是使用Add和ElementAt操作对列表进行并发访问。因为在你的情况下,ElementAt不必枚举列表,它将在内部检查列表是否为空,如果不是,它将返回指定索引处的元素,如list[index]。这非常轻量级,因此您的问题在于Add操作的来源。

Add操作首先在内部检查其当前容量是否足够大,以便可以添加新元素(它在内存中保留的位数多于它包含的元素数量+ 1)。如果可以添加它,只需通过语句_items[_size++] = item;

即可

如果之前未分配足够大小,Add操作将创建一个新数组,其中包含所需的新大小。之后,之前太小的数组中的元素需要复制到新数组中。这通过Array.Copy操作发生。之后,内部保持的元素数量增加,然后元素本身被添加。

正如你所看到的,幕后有很多事情要发生。我个人不知道问题究竟来自哪里。我最好的猜测是内部数组中的内存已经分配,​​但是在使用ElementAt操作访问它时未设置该值。

此类问题是您需要管理对共享资源(可跨线程共享的资源)的访问权限的原因。有几种技术可用于锁,监视器,信号量等......

您还可以将集合的类型更改为thread-safe collection,以处理同步问题。