C# 为什么c中有“null”?

C# 为什么c中有“null”?,c#,C#,我想在C中模拟producer-Consumer。一个线程作为producer,它将新数组对象放入列表中。另一个线程作为comsumer,当列表中有元素时,它获取数组并执行一些操作。代码在这里。为什么进程中有空值。如何修复它? 调用list.addtmp,list.Count时可能会导致问题,在ushort[]tmp准备就绪之前添加了一个。有人能解释这种过程的机制吗 using System; using System.Collections.Generic; using Sys

我想在C中模拟producer-Consumer。一个线程作为producer,它将新数组对象放入列表中。另一个线程作为comsumer,当列表中有元素时,它获取数组并执行一些操作。代码在这里。为什么进程中有空值。如何修复它? 调用list.addtmp,list.Count时可能会导致问题,在ushort[]tmp准备就绪之前添加了一个。有人能解释这种过程的机制吗

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

        }
    }

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

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

如果以前分配的大小不够,则添加操作将使用所需的新大小创建一个新数组。之后,需要将以前太小的数组中的元素复制到新数组中。这是通过Array.Copy操作实现的。之后,内部持有的元素计数增加,然后元素本身被添加

正如你所看到的,在幕后发生了很多事情。就我个人而言,我不知道问题的真正根源是什么。我的最佳猜测是,内部数组中的内存已经分配,但在使用ElementAt操作访问它时,没有设置该值

这些问题就是为什么您需要管理对可跨线程共享的共享资源的访问。有几种技术,如锁、监视器、信号灯等


您还可以将集合的类型更改为一个可以自行解决同步问题的类型。

设置断点并通过代码进行调试。嗯,两个线程具有非线程安全列表且没有锁,似乎您必须先阅读有关多线程编程的内容。可能重复@user1666620,这不太可能有帮助。调试多线程错误不是一项容易的任务。如何在func1@sounder中打破第一个while循环?有一个if(list.count>0,如果列表中没有元素,ushort[]data=list.ElementAt0将跳过。很抱歉,我一开始忽略了这条语句。我将很快为您提供更好的答案