为什么有“;空”;在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();
}
}
}
您有时会得到null的问题是通过操作Add和ElementAt同时访问您的列表。由于在您的情况下,ElementAt不必枚举列表,它只会在内部检查列表是否为null,如果不是,它会像list[index]
一样返回指定索引处的元素。这是非常轻量级的,所以问题在于Add操作的来源。
Add操作首先在内部检查其当前容量是否足够大,以便可以添加新元素(它在内存中保留的位置比它包含的元素数量+1还要多)。如果可以添加,则只需通过语句_items[_size++] = item;
即可添加
在之前分配的大小不够的情况下,Add操作会创建一个具有所需新大小的新数组。之后,需要将以前太小的数组中的元素复制到新数组中。这是通过Array.Copy
操作实现的。然后,内部保持的元素计数递增,然后添加元素本身。
正如你所看到的,幕后发生了很多事情。就我个人而言,我不知道问题的真正根源。我的最佳猜测是,内部数组中的内存已经分配,但在使用ElementAt操作访问它时没有设置值。
这些问题就是为什么您需要管理对共享资源(可以跨线程共享的资源)的访问。有几种技术可以做到这一点,比如锁、监视器、信号量。。。
您还可以将集合的类型更改为线程安全集合,该集合本身负责处理同步问题。