Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

【C#】ConcurrentQueueの使い方

Last updated at Posted at 2025-10-08

同じデータやファイルに複数のスレッドからアクセスされるものを安全に、順番に処理するための排他制御を行えるクラスConcurrentQueueについて簡単に記載していきます。

Queueとは

最初に追加された要素が最初に取り出される先入れ先出し(First In First Out)のデータ構造です。
C#にはQueueクラスもあり、ConcurrentQueueはスレッドセーフなQueueになります。

ConcurrentQueueの使い方

new ConcurrentQueue<型>()で作成。
Enqueueで追加、TryDequeueやTryPeekで要素の取得。

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;

    {
        var queue = new ConcurrentQueue<int>();
        // キューに追加
        queue.Enqueue(1);
        queue.Enqueue(2);
        // キューから要素を取得(キューからも削除)
        if (queue.TryDequeue(out int result1))
        {
            Console.WriteLine($"value: {result1}");
        }
        else
        {
            Console.WriteLine("Queue is empty.");
        }
        // キューから要素を取得(キューからは削除されない)
        if (queue.TryPeek(out int result2))
        {
            Console.WriteLine($"value: {result2}");
        }
        else
        {
            Console.WriteLine("Queue is empty.");
        }
    }

実装例

ConcurrentQueueを使用したログ出力を行うクラス

using System.Collections;
using System.Collections.Concurrent;

    public class Logger
    {
        private readonly string LogFilePath = "ファイルのパス";

        private readonly ConcurrentQueue<string> _logQueue = new();
        private readonly Thread _logThread;
        private readonly AutoResetEvent _logEvent = new(false);
        private bool _isRunning = true;

        public Logger()
        {
            _logThread = new Thread(ProcessLogQueue)
            {
                IsBackground = true
            };
            _logThread.Start();
        }

        public void Log(string message)
        {
            string timestampedMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
            _logQueue.Enqueue(timestampedMessage);
            _logEvent.Set(); // 通知してログスレッドを起こす
        }

        private void ProcessLogQueue()
        {
            while (_isRunning)
            {
                _logEvent.WaitOne(); // 通知があるまで待機

                while (_logQueue.TryDequeue(out string logMessage))
                {
                    try
                    {
                        // ログファイルに書き込み
                        File.AppendAllText(LogFilePath, logMessage + Environment.NewLine);
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine($"ログ書き込みエラー: {ex.Message}");
                    }
                }
            }
        }
    }

株式会社ONE WEDGE

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?