【问题标题】:Why there are "null" in c#? [closed]为什么c#中有“null”? [关闭]
【发布时间】:2016-01-05 09:49:59
【问题描述】:

我想在 C# 中模拟生产者消费者。一个线程作为生产者工作,新的数组对象,并将该数组放入 List。另一个线程作为消费者,当 List 中有元素时,它获取数组并执行某物。代码在这里。为什么过程中有“空”。如何解决? 调用list.add(tmp)时引起的问题,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();
            }

        }
    }

【问题讨论】:

  • 设置断点并通过代码进行调试。
  • hmm,2 个线程有一个非线程安全列表且没有锁,看来您必须先阅读有关多线程编程的知识。
  • @user1666620,这不太可能有帮助。调试多线程 bug 并非易事。
  • 如何跳出 func1 @sounder 中的第一个 while 循环?

标签: c#


【解决方案1】:

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

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

如果之前没有分配足够的大小,添加操作会创建一个具有所需新大小的新数组。之后,需要将以前太小的数组中的元素复制到新数组中。这通过Array.Copy 操作发生。之后,内部保存的元素计数增加,然后元素本身被添加。

如您所见,幕后发生了很多事情。就我个人而言,我不知道问题真正出在哪里。我最好的猜测是内部数组中的内存已经分配,​​但是当您使用 ElementAt 操作访问它时,该值没有设置。

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

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

【讨论】:

  • 有一个 if(list.count>0) ,如果列表中没有元素,ushort[] data = list.ElementAt(0) 会绕过。
  • 对不起,我一开始忽略了这个说法。我会尽快为您提供更好的答案
猜你喜欢
  • 2013-02-12
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2016-07-22
  • 2013-06-11
  • 1970-01-01
相关资源
最近更新 更多