フッターコンテンツにスキップ
.NETヘルプ

C# Concurrent List (開発者向けの仕組み)

もし複数のスレッドが共有リソースへのアクセスを争っていることがあったなら、スレッドセーフな実装がゲームではないことをご存じでしょう。 しかし心配しないでください! C#にはコンカレントコレクションがあります - スレッドの安全性をスタイルと優雅さで確保する強力なスイートのスレッドセーフな汎用コレクションクラスです。

Thread Safety and Concurrent Collections in C

交通信号がない忙しい都市の交差点を思い描きましょう。 混乱を想像できますか! これは、適切なシステムがない場合に複数のスレッドが同時に共有リソースにアクセスする際に発生する現象と似ています。 幸いなことに、C#ではスレッドの交通信号があります - それがコンカレントコレクションと呼ばれます。 これらは、一度に一つのスレッドがリソースにアクセスできるようにするコレクションクラスです。このスレッドセーフティは、複数のスレッドを扱う際に重要です。

Exploring Concurrent Thread Safe Collections in C

C# では、名前空間 System.Collections.Concurrent には、ConcurrentBag などのさまざまな同時実行コレクション クラスがあります。 これらの無秩序なコレクションクラスは、非コンカレントの対応するクラスのスレッドセーフ版を提供します。 コンカレントコレクションを他と区別するのは、それが無秩序なコンカレントコレクションであるということであり、要素に特定の順序がないことを意味します。 例えば、コンカレントリストでは、要素がどこに挿入されるのか正確にはわかりません。 注目すべきは、スレッドセーフティを確保することであり、順序を維持することではありません。

実生活の例を見てみましょう。 ウェブサイト上でのパスワード提出の投稿を考えてみてください。コンカレントコレクションを使用すると、複数のユーザーが同時にパスワードを提出できます。 各"提出"アクションはスレッドのようであり、コンカレントコレクションは各提出がスレッドセーフで、安全かつ効果的に処理されることを保証します。

ConcurrentDictionary: 実例

それでは、実際の例を使って、ConcurrentDictionary コレクション クラスを調べてみましょう。 オンライン書店での推奨機能をイメージしてください。 各ユーザーのクリックが、辞書で表された彼らの個人的な推奨リストに本を追加します。 複数のユーザーが同時に本を閲覧しクリックするため、辞書に同時にアクセスする複数のスレッドがあります。

C# の ConcurrentDictionary は次のようになります。

using System.Collections.Concurrent;

ConcurrentDictionary<string, string> recommendedBooks = new ConcurrentDictionary<string, string>();
using System.Collections.Concurrent;

ConcurrentDictionary<string, string> recommendedBooks = new ConcurrentDictionary<string, string>();
$vbLabelText   $csharpLabel

ユーザーの推奨コレクション全体に書籍を追加するには、TryAdd メソッドを使用できます。

public void Insert(string user, string book)
{
    // Try to add the book to the user's recommendations
    recommendedBooks.TryAdd(user, book);
}
public void Insert(string user, string book)
{
    // Try to add the book to the user's recommendations
    recommendedBooks.TryAdd(user, book);
}
$vbLabelText   $csharpLabel

このシナリオでは、 ConcurrentDictionary コレクションクラスがすべてのクリック(または"スレッド")を個別に処理するため、複数のユーザーの推奨事項が混同されることはありません。スレッドセーフティはすべてこのクラスが処理するため、データ競合や複数スレッドに関連するその他の同時実行性の問題を心配する必要はありません。

スレッドセーフな操作の実装

TryAdd 以外にも、C# の同時実行コレクションでは、TryRemoveTryUpdate などのさまざまなスレッドセーフな操作が提供されます。 これらのメソッドは、一度に1つのスレッドのみが操作を実行できるようにします。例えば、前の例でユーザーのおすすめから書籍を削除したい場合は、TryRemove メソッドを使用できます。

public void RemoveAt(string user)
{
    // Attempt to remove the book for the specified user
    string removedBook;
    recommendedBooks.TryRemove(user, out removedBook);
}
public void RemoveAt(string user)
{
    // Attempt to remove the book for the specified user
    string removedBook;
    recommendedBooks.TryRemove(user, out removedBook);
}
$vbLabelText   $csharpLabel

TryRemove メソッドは、指定されたキー (この場合はユーザー) の値を削除し、それを removedBook 変数に格納しようとします。

コンカレントコレクションのコピー

さて、同時コレクションを配列にコピーしたいとしましょう。 並行コレクションはまさにこの目的のために CopyTo メソッドを提供します:

public void CopyTo()
{
    // Create an array to hold the recommended books
    string[] bookArray = new string[recommendedBooks.Count];

    // Copy the values of the concurrent dictionary to the array
    recommendedBooks.Values.CopyTo(bookArray, 0);
}
public void CopyTo()
{
    // Create an array to hold the recommended books
    string[] bookArray = new string[recommendedBooks.Count];

    // Copy the values of the concurrent dictionary to the array
    recommendedBooks.Values.CopyTo(bookArray, 0);
}
$vbLabelText   $csharpLabel

ここで、CopyTo メソッドは、recommendedBooks 同時実行辞書からすべてのブック (値) を bookArray にコピーします。

スレッドセーフコレクション

C#はマルチスレッド環境で共有リソースへの安全なアクセスを保証するスレッドセーフコレクションも提供します。 ConcurrentStack などのコレクションは、競合やデータ破損を引き起こすことなく、複数のスレッドが同時にコレクションにアクセスして変更できるスレッドセーフな実装を提供します。

内部的に同期を処理することで一貫性と完全性を保証し、無秩序なコレクションが十分で、C#アプリケーションでスレッドセーフティが最も重要なシナリオに理想的です。

IronPDFの詳細を学ぶは、HTMLからPDFドキュメントを簡単に生成するための人気のあるC#ライブラリです。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
$vbLabelText   $csharpLabel

最初はコンカレントリストとは直接関係ないように見えますが、IronPDFはコンカレントコレクション操作を補完し、コンカレント処理の結果をキャプチャする報告書やログ、その他のドキュメントを作成する簡単な方法を提供します。

集中的なデータ処理を行うマルチスレッドアプリケーションがあるシナリオを考えてみてください。 スレッドがデータを魔法にかけている間に、結果をキャプチャし、さらなる分析や記録のためにPDFレポートを生成したくなるかもしれません。 ここでIronPDFが役立ちます。

IronPDFを使用するのは、ライブラリをプロジェクトに追加し、その便利なAPIを利用するだけです。 IronPDFをコンカレントコレクション操作と統合する方法の例を次に示します:

using IronPdf;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

// Create a concurrent dictionary to hold your processed data
ConcurrentDictionary<int, string> processedData = new ConcurrentDictionary<int, string>();

// Define your data list (replace with your actual data source)
List<DataItem> dataList = GetDataList();

// Process your data concurrently and store the results in the dictionary
Parallel.ForEach(dataList, (dataItem) =>
{
    // Process each data item and add the result to the dictionary
    string processedResult = ProcessDataItem(dataItem);
    processedData.TryAdd(dataItem.Id, processedResult);
});

// Generate a PDF report with the processed data
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(BuildHtmlReport(processedData));
pdfDocument.SaveAs("C:\\processed_data_report.pdf");

// Method to retrieve the data list (replace with your actual data source logic)
List<DataItem> GetDataList()
{
    List<DataItem> dataList = new List<DataItem>()
    {
        new DataItem { Id = 1, Name = "Item 1" },
        new DataItem { Id = 2, Name = "Item 2" },
        new DataItem { Id = 3, Name = "Item 3" },
        new DataItem { Id = 4, Name = "Item 4" }
    };
    return dataList;
}

// Method to process each data item and return the result (replace with your actual data processing logic)
string ProcessDataItem(DataItem dataItem)
{
    // Simulating data processing with a delay
    Task.Delay(100).Wait();
    return $"Processed: {dataItem.Name}";
}

// Method to build the HTML report using the processed data (replace with your actual reporting logic)
string BuildHtmlReport(ConcurrentDictionary<int, string> processedData)
{
    string html = "<h1>Processed Data Report</h1><ul>";
    foreach (var kvp in processedData)
    {
        html += $"<li>Item {kvp.Key}: {kvp.Value}</li>";
    }
    html += "</ul>";
    return html;
}

// Placeholder class for your data item (replace with your actual data item class)
public class DataItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Add other properties as needed
}
using IronPdf;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

// Create a concurrent dictionary to hold your processed data
ConcurrentDictionary<int, string> processedData = new ConcurrentDictionary<int, string>();

// Define your data list (replace with your actual data source)
List<DataItem> dataList = GetDataList();

// Process your data concurrently and store the results in the dictionary
Parallel.ForEach(dataList, (dataItem) =>
{
    // Process each data item and add the result to the dictionary
    string processedResult = ProcessDataItem(dataItem);
    processedData.TryAdd(dataItem.Id, processedResult);
});

// Generate a PDF report with the processed data
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(BuildHtmlReport(processedData));
pdfDocument.SaveAs("C:\\processed_data_report.pdf");

// Method to retrieve the data list (replace with your actual data source logic)
List<DataItem> GetDataList()
{
    List<DataItem> dataList = new List<DataItem>()
    {
        new DataItem { Id = 1, Name = "Item 1" },
        new DataItem { Id = 2, Name = "Item 2" },
        new DataItem { Id = 3, Name = "Item 3" },
        new DataItem { Id = 4, Name = "Item 4" }
    };
    return dataList;
}

// Method to process each data item and return the result (replace with your actual data processing logic)
string ProcessDataItem(DataItem dataItem)
{
    // Simulating data processing with a delay
    Task.Delay(100).Wait();
    return $"Processed: {dataItem.Name}";
}

// Method to build the HTML report using the processed data (replace with your actual reporting logic)
string BuildHtmlReport(ConcurrentDictionary<int, string> processedData)
{
    string html = "<h1>Processed Data Report</h1><ul>";
    foreach (var kvp in processedData)
    {
        html += $"<li>Item {kvp.Key}: {kvp.Value}</li>";
    }
    html += "</ul>";
    return html;
}

// Placeholder class for your data item (replace with your actual data item class)
public class DataItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Add other properties as needed
}
$vbLabelText   $csharpLabel

ここにコードの出力があります:

C# 並行リスト (開発者向けの仕組み) 図 1 - 出力

結論

結論として、C#のコンカレントコレクション、例えばコンカレントリストを理解し、利用することは、マルチスレッドシナリオを効率的に処理し、アプリケーションでスレッドセーフティを確保する能力を大幅に向上させます。 コンカレントコレクションを使用することで、共有リソースを効果的に管理し、スレッド間のデータ競合や衝突を防ぐことができます。

外部ライブラリのIronPDFを統合することで、視覚的に魅力的なPDFレポートやドキュメントの生成を可能にし、コンカレントコレクションの機能をさらに拡張できます。 IronPDF は、 HTML から PDF への変換ライブラリの無料トライアルを提供しており、その機能やライセンス オプションを $799 から試すことができます。

よくある質問

C# の同時実行コレクションとは?

C# の同時実行コレクションは、複数のスレッドが共有リソースにアクセスするときのスレッド セーフ性を確保する、スレッド セーフなジェネリック コレクション クラスのスイートです。

なぜ C# でのスレッド セーフティが重要なのですか?

C# でのスレッド セーフティは、複数のスレッドが共有リソースに同時にアクセスして変更する際に、混乱やデータの破損を防ぐために重要です。操作が制御された方法で実行されることを保証します。

C# でスレッドセーフなリストを作成するにはどうすればよいですか?

C# では直接スレッドセーフな List クラスは提供されていませんが、`ConcurrentBag` や `ConcurrentDictionary` などの他の同時実行コレクションを使用して、同様のスレッドセーフな操作を行うことができます。

C# の ConcurrentDictionary とは?

C# の ConcurrentDictionary は、`System.Collections.Concurrent` 名前空間内のスレッド セーフなコレクションクラスです。複数のスレッドがキーと値のペアを同時に安全に追加、更新、および削除できるようにします。

ConcurrentDictionary はどのようにしてスレッド セーフティを確保しますか?

ConcurrentDictionary は内部的に同期を処理し、1 回に 1 つのスレッドのみがアイテムの追加や削除などの操作を実行できるようにすることで、スレッド セーフティを確保します。

ConcurrentDictionary にアイテムを追加するにはどうすればよいですか?

TryAdd メソッドを使用して ConcurrentDictionary にアイテムを追加できます。このメソッドは、キーが既に辞書に存在しない場合にのみキーと値のペアを追加しようとします。

Concurrent コレクションの CopyTo メソッドの目的は何ですか?

同時実行コレクションの CopyTo メソッドは、コレクションの要素を配列にコピーするために使用され、コレクションから別のストレージ形式にデータを転送するための方法を提供します。

IronPDF を使用して処理済みデータから PDF レポートを生成できますか?

はい、IronPDF を使用して、同時実行操作の結果をキャプチャし、マルチスレッド アプリケーションによって処理されたデータから PDF レポートを生成できます。

IronPDF を使用することで、同時実行操作の機能はどのように強化されますか?

IronPDF は、プロセスされたデータから PDF ドキュメントを作成できるようにすることで、同時実行操作を強化し、マルチスレッド処理の結果を文書化して共有する方法を提供します。

マルチスレッドの C# アプリケーションで IronPDF が果たす役割は何ですか?

IronPDF を使用すると、開発者は並列で処理されたデータから PDF レポートを生成でき、マルチスレッド操作からの結果を統合して共有しやすくなります。

Jacob Mellor、Ironチームの最高技術責任者(CTO)
最高技術責任者(CTO)

ジェイコブ・メラーはIron Softwareの最高技術責任者(CTO)であり、C# PDFテクノロジーを開拓する先見的なエンジニアです。Iron Softwareのコアコードベースを支えるオリジナル開発者として、彼は創業以来、会社の製品アーキテクチャを形成し、CEOのCameron Rimingtonとともに、会社をNASA、Tesla、および世界的な政府機関にサービスを提供する50人以上の会社に変えました。1999年にロンドンで最初のソフトウェアビジネスを開業し、2005年に最初 for .NETコンポーネントを作成した後、Microsoftのエコシステム全体で複雑な問題を解決することを専門としました。

彼の主要なIronPDFとIron Suite .NETライブラリは、世界中で3000万以上のNuGetインストールを達成し、彼の基礎となるコードは世界中で使用されている開発者ツールに力を与え続けています。25年の商業経験と41年のコーディングの専門知識を持つJacobは、次世代の技術リーダーを指導しながら、エンタープライズグレードのC#、Java、Python PDFテクノロジーにおけるイノベーションの推進に注力しています。

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me