Ⅰ. はじめに
タイトルの通り「C#で非同期かつ優先度考慮可能なQueueを利用する方法」です。
非同期ではないPriorityQueueは.NET6で実装されました
Ⅱ. やり方
1. 必要なパッケージをNuGetからインストールする
dotnet add package ConcurrentDataStructures --version 0.2.0
2. サンプルプログラムを書く
※簡単の為非同期らしい動きは省きます
using DataStructures;
namespace Test
{
class Program
{
class MyQueue : IComparable<MyQueue>
{
public int Id { get; set; }
public int Priority { get; set; }
public int CompareTo(MyQueue x)
{
return Priority - x.Priority;
}
}
static void Main(string[] args)
{
var queue = new ConcurrentPriorityQueue<MyQueue>();
queue.TryAdd(new MyQueue { Id = 1, Priority = 100 });
queue.TryAdd(new MyQueue { Id = 2, Priority = 999 });
queue.TryAdd(new MyQueue { Id = 3, Priority = 200 });
while (true)
{
if (queue.TryTake(out var x))
{
Console.WriteLine($"Id: {x.Id}, Priority: {x.Priority}");
}
else
{
break;
}
}
}
}
}
実行結果
Id: 2, Priority: 999
Id: 3, Priority: 200
Id: 1, Priority: 100
留意点(2022/08/18追記)
- 以下プログラムは途中でID5を挿入する。このときID2よりもID5が先に取り出される。
つまり、CompareToの条件が最優先される。
(Queueの動きとして妥当では無い気もしますが…)
using DataStructures;
using System;
namespace Test
{
class Program
{
class MyQueue : IComparable<MyQueue>
{
public int Id { get; set; }
public int Priority { get; set; }
public int CompareTo(MyQueue x)
{
return Priority - x.Priority;
}
}
static void Main(string[] args)
{
var queue = new ConcurrentPriorityQueue<MyQueue>();
queue.TryAdd(new MyQueue { Id = 1, Priority = 100 });
queue.TryAdd(new MyQueue { Id = 2, Priority = 100 });
queue.TryAdd(new MyQueue { Id = 3, Priority = 999 });
queue.TryAdd(new MyQueue { Id = 4, Priority = 200 });
while (true)
{
if (queue.TryTake(out var x))
{
Console.WriteLine($"Id: {x.Id}, Priority: {x.Priority}");
if (x.Id == 4)
{
queue.TryAdd(new MyQueue { Id = 5, Priority = 100 });
}
}
else
{
break;
}
}
}
}
}