Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sort a queue in C#

Even though this question sounds as a duplicate, I searched a lot but couldn't find a proper solution.

I have following classes

public enum ChangeType
{ 
    Add,
    Modify,
    Delete
}



public enum ChangedObjectType
{ 
    Project,
    Customer,
    Border,
    Photo
}

public struct ChangeInfo
{
    public ChangeType typeofChange { get; private set; }
    public ChangedObjectType objectType { get; private set; }

    public string objectID { get; private set; }

    public ChangeInfo(ChangeType changeType, ChangedObjectType changeObj, string objectId):this()
    {
        typeofChange = changeType;
        objectType = changeObj;
        objectID = objectId;
    }

}

thread :

public class ChangeInfoUploader
{ 
    static Queue<ChangeInfo> changeInfoQueue = new Queue<ChangeInfo>();
    static Thread changeInfoUploaderThread = new Thread(new ThreadStart(ChangeInfoUploaderProc));
    static bool isStarted = false;
    static Project currentProject;

    public static void Initialize(Project curproject)
    {
        currentProject = curproject;
        isStarted = true;
        changeInfoUploaderThread.Start();
        ResumeData();
    }

    static void ChangeInfoUploaderProc()
    {
        while (isStarted)
        {
            if (currentProject != null)
            {
                ChangeInfo? addToDb = null;

             // I need to sort changeInfoQueue before dequeue
                lock (changeInfoQueue)
                {
                    if (changeInfoQueue.Count != 0)
                        addToDb = changeInfoQueue.Dequeue();
                }
            }
        }
        Logdata();
        changeInfoUploaderThread.Abort();
    }
}

here is the sample data of changeInfoQueue queue.

<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0005" />
<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0006" />
<Info TypeofChange="Add" ObjectType="Customer" ObjectId="0007" />
<Info TypeofChange="Add" ObjectType="Photo" ObjectId="01a243f5-4894-4d99-8238-9c4cd3" />

My Question :

  • I need to sort out changeInfoQueue based on ObjectType. How can i do that?

My findings:

  • I found OrderBy . Is it possible to use it? If so, how?

In addition to that I found priorityQueue. What is the best solution for me?

EDIT:

The values of this queue are added when relevant objects are created. (projects, borders etc.) and saves it in a local XML file. After that it needs to write to a database. This is accomplished by using a thread and when we save this data it must be saved in particular order to avoid foreign key violations. So this thread is used to call those relevant methods.

I used orderby as follows:

Queue<ChangeInfo> changeInfoQueue2 = changeInfoQueue.OrderBy(ChangeInfo => ChangeInfo.ObjectType);

then it throws following exception:

Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Collections.Generic.Queue'. An explicit conversion exists (are you missing a cast?)

like image 596
DevT Avatar asked Nov 30 '22 01:11

DevT


2 Answers

Why would you want to order by the type of object in a queue? A queue, by its definition, it's not meant to be ordered in that way but intended to work as a first in first out kind of element.

Either use a List if you just want a collection capable of being ordered, and ordered list or create several queues for the different kind of objects that you have.

For example, if you go to the super market you have several queues, one for each different section... it wouldn't make any sense to put all people in the same queue and then "order" them based on whether they are in for the butcher or the bakery.

You have a queue when you need to "queue" things... if you don't use the appropriate construct, don't try to force it into a queue. ("if you have a hammer everything looks like a nail"... but it should not)

like image 54
Jorge Córdoba Avatar answered Dec 06 '22 20:12

Jorge Córdoba


While everything that has been said about using queue and OrderBy is valid, you still might want to order elements in your queue.

You can build a new queue based on a IOrderedEnumerable:

Queue<string> queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
queue.Enqueue("third");
queue.Enqueue("fourth");

// Builds a new queue. Items are now alphabetically ordered
Queue<string> orderedQueue = new Queue<string>(queue.OrderBy(z => z));
like image 40
ken2k Avatar answered Dec 06 '22 20:12

ken2k