为什么有“;空”;在c#中

本文关键字:为什么 | 更新日期: 2023-09-27 18:29:09

我想在C#中模拟生产者-消费者。一个线程充当生产者,哪些新的数组对象,并将该数组放在List中。另一个线程作为comsumer,当List中有元素时,它获取数组并做些什么。代码在这里。为什么流程中存在"null"。如何修复?调用list.add(tmp),list时可能导致的问题。在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();
            }
        }
    }

为什么有“;空”;在c#中

您有时会得到null的问题是通过操作Add和ElementAt同时访问您的列表。由于在您的情况下,ElementAt不必枚举列表,它只会在内部检查列表是否为null,如果不是,它会像list[index]一样返回指定索引处的元素。这是非常轻量级的,所以问题在于Add操作的来源。

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

在之前分配的大小不够的情况下,Add操作会创建一个具有所需新大小的新数组。之后,需要将以前太小的数组中的元素复制到新数组中。这是通过Array.Copy操作实现的。然后,内部保持的元素计数递增,然后添加元素本身。

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

这些问题就是为什么您需要管理对共享资源(可以跨线程共享的资源)的访问。有几种技术可以做到这一点,比如锁、监视器、信号量。。。

您还可以将集合的类型更改为线程安全集合,该集合本身负责处理同步问题。