C#返回ConcurrentBag的副本

时间:2015-06-08 12:03:13

标签: c# multithreading

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace Crystal_Message
{
    class Message
    {
        private int messageID;
        private string message;
        private ConcurrentBag <Employee> messageFor;
        private Person messageFrom;
        private string calltype;

        public Message(int iden,string message, Person messageFrom, string calltype, string telephone)
        {
            this.messageID = iden;
            this.messageFor = new ConcurrentBag<Employee>();
            this.Note = message;
            this.MessageFrom = messageFrom;
            this.CallType = calltype;
        }

        public ConcurrentBag<Employee> ReturnMessageFor
        {
            get
            {

                return messageFor;
            }

        }

        public int MessageIdentification
        {
            get { return this.messageID; }

            private set
            {
                if(value == 0)
                {
                    throw new ArgumentNullException("Must have Message ID");
                }

                this.messageID = value;
            }

        }

        public string Note
        {
            get { return message; }

            private set
            {
                if (string.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("Must Have a Message");

                }
                this.message = value;


            }

        }

        public Person MessageFrom
        {
            get { return messageFrom; }

            private set
            {
                this.messageFrom = value;
            }

        }

        public string CallType
        {
            get { return this.calltype; }

            private set
            {
                if (string.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentNullException("Please specify call type");
                }

                this.calltype = value;

            }

        }

        public void addEmployee(Employee add)
        {
            messageFor.Add(add);
        }


        public override string ToString()
        {
            return "Message: " + this.message + " From: " + this.messageFrom + " Call Type: " + this.calltype + " For: " + this.returnMessagefor();
        }

        private string returnMessagefor() 
        {
            string generate="";

            foreach(Employee view in messageFor)
            {
                generate += view.ToString() + " ";
            }

            return generate;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            Message testEquals = obj as Message;

            if((System.Object)testEquals == null)
            {
                return false;
            }

            return (this.messageID == testEquals.messageID) && (this.message == testEquals.message) && (this.messageFor == testEquals.messageFor) && (this.messageFrom == testEquals.messageFrom) && (this.calltype == testEquals.calltype);

        }

        public bool Equals(Message p)
        {
            if ((Object)p == null)
            {
                return false;
            }

            return (this.messageID == p.messageID) && (this.message == p.message) && (this.messageFor == p.messageFor) && (this.messageFrom == p.messageFrom) && (this.calltype == p.calltype);

        }

        public override int GetHashCode()
        {


            unchecked
            {
                return this.messageID.GetHashCode() * 33 ^ this.message.GetHashCode() * 33 ^ this.messageFor.GetHashCode() * 33 ^ this.messageFrom.GetHashCode() * 33 ^ this.calltype.GetHashCode();
            }


        }

    }
}

我有一个Message类,用户可以为多个人留言。我有一个吸气剂,然而,返回一个ConcurrentBag&lt;&gt;我做正确练习的方式?如果没有,我如何返回ConcurrentBag&lt;&gt;所以我可以循环显示它并显示它?

2 个答案:

答案 0 :(得分:6)

ConcurrentBag<T>IEnumerable<T>。你可以照常循环播放它。但是,由于这是一个线程安全的集合,因此使用它会产生性能问题。

如果您想在循环时摆脱性能影响,请在其上调用ToArray并返回新阵列。

    public IEnumerable<Employee> ReturnMessageFor
    {
        get
        {

            return messageFor.ToArray();
        }

    }

答案 1 :(得分:2)

我不清楚你想要完成什么。

您是否尝试将Bag外部化以进行所有操作?因为那就是你做的......

如果你想要外化你可以迭代的东西,你应该将Bag作为IEnumerable返回,或者返回一个数组或从Bag复制的列表。

无论哪种方式,迭代都是安全的。在性能方面可能不是最好的,但这是另一个问题。

    // Option 1
    public IEnumerable<Employee> ReturnMessageFor
    {
        get
        {
            return messageFor;
        }
    }

    // Option 2
    public Employee[] ReturnMessageFor
    {
        get
        {
            return messageFor.ToArray();
        }
    }

注意:

  • 您可能想要readonly发送message(在您发布的代码中只读取)。
  • 请记住,ConcurrentBag允许您以线程安全的方式安全地迭代集合的快照,但它不会锁定集合中的项目。