C# 为什么c中有“null”?
我想在C中模拟producer-Consumer。一个线程作为producer,它将新数组对象放入列表中。另一个线程作为comsumer,当列表中有元素时,它获取数组并执行一些操作。代码在这里。为什么进程中有空值。如何修复它? 调用list.addtmp,list.Count时可能会导致问题,在ushort[]tmp准备就绪之前添加了一个。有人能解释这种过程的机制吗C# 为什么c中有“null”?,c#,C#,我想在C中模拟producer-Consumer。一个线程作为producer,它将新数组对象放入列表中。另一个线程作为comsumer,当列表中有元素时,它获取数组并执行一些操作。代码在这里。为什么进程中有空值。如何修复它? 调用list.addtmp,list.Count时可能会导致问题,在ushort[]tmp准备就绪之前添加了一个。有人能解释这种过程的机制吗 using System; using System.Collections.Generic; using Sys
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将跳过。很抱歉,我一开始忽略了这条语句。我将很快为您提供更好的答案