IRONSOFTWAREHOME

Jak używać asynchroniczności i wielowątkowości do operacji z kodami QR w języku C#

Curtis Chau
Curtis Chau
Updated: 6 marca 2026

Skanowanie kodów QR w trybie jednowątkowym blokuje wątek wywołujący na czas dekodowania każdego obrazu.

W procedurze obsługi przycisku WPF powoduje to zawieszenie interfejsu użytkownika do czasu zakończenia dekodowania. W zadaniu wsadowym przetwarzającym setki obrazów pozostawia rdzenie procesora bezczynne, podczas gdy mogłyby one pracować równolegle. Metoda ReadAsync z IronQR przesyła poszczególne odczyty do zadania awaitable, a standardowa metoda Read działa z Parallel.ForEach i Task.WhenAll dla przepustowości wsadowej.

W niniejszym przewodniku pokazano, jak przetwarzać kody QR asynchronicznie, rozdzielać odczyty partii między rdzenie procesora oraz łączyć oba wzorce w przypadku potoków o dużej przepustowości.

Szybki start: Asynchroniczne przetwarzanie kodów QR

Załaduj obraz i poczekaj na zdekodowane wyniki bez blokowania wątku wywołującego.

  1. 1Install IronQR with NuGet Package Manager

    PM > Install-Package IronQR

  2. 2Skopiuj i uruchom ten fragment kodu.

    using IronQr;
    using IronSoftware.Drawing;
    
    var input = new QrImageInput(AnyBitmap.FromFile("ticket.png"));
    IEnumerable<QrResult> results = await new QrReader().ReadAsync(input);
    Console.WriteLine(results.First().Value);
    C#
  3. 3Wdrożenie do testowania w środowisku produkcyjnym

    Rozpocznij używanie IronQR w swoim projekcie już dziś z darmową wersją próbną
    arrow pointer

Asynchroniczne odczytywanie kodów QR

ReadAsync zwraca zadanie awaitable, co czyni go kompatybilnym z obsługą zdarzeń WPF/MAUI, akcjami kontrolera ASP.NET lub dowolną metodą asynchroniczną. Dane wejściowe muszą być utworzone z bitmapy obrazu; nie ma przeciążenia ścieżki pliku.

Strona pisania jest synchroniczna i nie ma wariantów asynchronicznych. Aby uniknąć blokowania wątku podczas operacji I/O na plikach, otocz krok zapisywania w File.WriteAllBytesAsync() używając surowych bajtów eksportowanych z bitmapy.

Dane wejściowe

Identyfikator wydarzenia w postaci kodu QR zeskanowany i wygenerowany ponownie w celu zademonstrowania asynchronicznego wzorca odczytu i zapisu.

Kodowanie kodu QR https://ironsoftware.com/event-badge używane jako asynchroniczne odczytywanie danych wejściowych
using IronQr;
using IronQr.Enum;
using IronSoftware.Drawing;

// --- Async read: non-blocking QR decode ---
var inputBmp = AnyBitmap.FromFile("event-badge.png");
var imageInput = new QrImageInput(inputBmp, QrScanMode.Auto);

var reader = new QrReader();
IEnumerable<QrResult> results = await reader.ReadAsync(imageInput);

foreach (QrResult result in results)
{
    Console.WriteLine($"[{result.QrType}] {result.Value}");
}

// --- Async-wrapped save: QrWriter.Write() and QrCode.Save() are synchronous ---
QrCode qrCode = QrWriter.Write("https://ironsoftware.com");
AnyBitmap qrImage = qrCode.Save();

// Save the bitmap bytes asynchronously (not an IronQR API — standard .NET async I/O)
byte[] pngBytes = qrImage.ExportBytes();
await File.WriteAllBytesAsync("output-qr.png", pngBytes);
C#

Wynik

Terminal wyświetla dekodowany typ QR i wartość w formacie [QrType] Value, a następnie potwierdza, że output-qr.png został zapisany.

Wynik na terminalu pokazujący zdekodowaną wartość [QR] oraz potwierdzenie zapisania pliku output-qr.png

QrScanMode.Auto uruchamia zarówno wykrywanie ML, jak i podstawowe skanowanie, wypełniając zdekodowaną wartość i typ QR w każdym wyniku. OnlyDetectionModel jest szybszy, ale zwraca tylko współrzędne pola ograniczającego, pozostawiając pole wartości puste. Użyj Auto zawsze, gdy potrzebna jest zakodowana treść.


Przetwarzanie kodów QR z wykorzystaniem wielowątkowości

Dla obrazów, które można dekodować niezależnie, Parallel.ForEach rozdziela pracę między dostępne rdzenie CPU. Oddzielna instancja QrReader na każdą iterację jest bezpiecznym domyślnym wyborem, ponieważ IronQR nie zapewnia wyraźnej gwarancji bezpieczeństwa wątków dla współdzielonych instancji czytników.

Dane wejściowe

Cztery z dziesięciu obrazów testowych kodów QR użytych w równoległym skanowaniu partii. Każdy obraz koduje URL i jest odczytywany z folderu qr-images/ w czasie wykonywania.

Wejściowy obraz kodu QR w partii 1 z 10 kodujący https://ironsoftware.com/batch-1

Zdjęcie 1 (partia 1 z 10)

Wejściowy obraz kodu QR w partii 2 z 10 kodujący https://ironsoftware.com/batch-2

Zdjęcie 2 (partia 2 z 10)

Wejściowy obraz kodu QR w partii 3 z 10 kodujący https://ironsoftware.com/batch-3

Zdjęcie 3 (partia 3 z 10)

Wejściowy obraz kodu QR w partii 4 z 10 kodujący https://ironsoftware.com/batch-4

Zdjęcie 4 (partia 4 z 10)

using IronQr;
using IronQr.Enum;
using IronSoftware.Drawing;
using System.Collections.Concurrent;
using System.Diagnostics;

string[] files = Directory.GetFiles("qr-images/", "*.png");
var allResults = new ConcurrentBag<(string File, string Value)>();
int failCount = 0;
var sw = Stopwatch.StartNew();

Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, file =>
{
    try
    {
        var input = new QrImageInput(
            AnyBitmap.FromFile(file),
            QrScanMode.Auto);

        // Per-thread QrReader instance — safe default
        var results = new QrReader().Read(input);

        foreach (QrResult result in results)
        {
            allResults.Add((Path.GetFileName(file), result.Value));
        }
    }
    catch (Exception ex)
    {
        Interlocked.Increment(ref failCount);
        Console.Error.WriteLine($"[ERROR] {Path.GetFileName(file)}: {ex.Message}");
    }
});

sw.Stop();

Console.WriteLine($"Processed {files.Length} files in {sw.Elapsed.TotalSeconds:F1}s");
Console.WriteLine($"QR codes found: {allResults.Count} | Failures: {failCount}");
Console.WriteLine($"Throughput: {files.Length / sw.Elapsed.TotalSeconds:F1} files/sec");
C#

Wynik

Konsola wyświetla podsumowanie partii, w tym liczbę przetworzonych plików, czas przetwarzania, znalezione kody QR, ewentualne błędy oraz przepustowość. Następnie podaje każdą nazwę pliku wraz z jego zdekodowanym adresem URL.

Wynik terminala pokazujący równoległe wyniki partii: 10 przetworzonych plików, znalezione kody QR, błędy, przepustowość i zdekodowany adres URL na nazwę pliku

Pobierz wszystkie 10 obrazów testowych do wprowadzania kodów QR (batch-qr-images.zip).

ConcurrentBag<t> zbiera wyniki ze wszystkich wątków bez potrzeby użycia blokad. Licznik bezpieczny dla wątków śledzi awarie, a użycie try-catch dla każdego pliku gwarantuje, że jeden uszkodzony obraz nie przerwie całej partii. Podejście to jest zgodne z wzorcem izolacji błędów opisanym w poradniku dotyczącym obsługi błędów.

Ustaw MaxDegreeOfParallelism na Environment.ProcessorCount, aby dopasować do liczby rdzeni CPU. Użycie dodatkowych wątków zwiększa obciążenie i nie poprawia wydajności, szczególnie w przypadku modeli ML wymagających dużej mocy obliczeniowej procesora.


Łączenie przetwarzania asynchronicznego i równoległego

Dla wysokoprzepustowych kolejek połącz SemaphoreSlim z Task.WhenAll, aby ograniczyć współbieżność. W przeciwieństwie do Parallel.ForEach, ten wzorzec utrzymuje I/O w trybie nieblokującym, jednocześnie kontrolując liczbę jednoczesnych dekodowań, zapobiegając nasyceniu puli wątków przy dużych obciążeniach.

Dane wejściowe

Cztery z dwudziestu testowych obrazów kodów QR przetworzonych przez współbieżną kolejkę. Każdy obraz koduje URL i jest dekodowany równolegle przy użyciu ograniczonej współbieżności przez SemaphoreSlim.

Obraz wejściowy kodu QR w potoku 1 z 20

Zdjęcie 1 (Potok 1 z 20)

Obraz wejściowy kodu QR w potoku 2 z 20

Zdjęcie 2 (Pipeline 2 z 20)

Obraz wejściowy kodu QR w potoku 3 z 20

Zdjęcie 3 (Pipeline 3 z 20)

Obraz wejściowy kodu QR w potoku 4 z 20

Zdjęcie 4 (Pipeline 4 z 20)

using IronQr;
using IronQr.Enum;
using IronSoftware.Drawing;
using System.Collections.Concurrent;
using System.Diagnostics;

string[] files = Directory.GetFiles("high-volume/", "*.png");
var results = new ConcurrentBag<(string File, string Value)>();
int maxConcurrency = Environment.ProcessorCount;
using var semaphore = new SemaphoreSlim(maxConcurrency);
var sw = Stopwatch.StartNew();

var tasks = files.Select(async file =>
{
    await semaphore.WaitAsync();
    try
    {
        var bmp = AnyBitmap.FromFile(file);
        // Auto: runs ML detection plus a basic scan so result.Value is populated
        var input = new QrImageInput(bmp, QrScanMode.Auto);
        var qrResults = await new QrReader().ReadAsync(input);

        foreach (var qr in qrResults)
        {
            results.Add((Path.GetFileName(file), qr.Value));
        }
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine($"{{\"file\":\"{Path.GetFileName(file)}\",\"error\":\"{ex.Message}\"}}");
    }
    finally
    {
        semaphore.Release();
    }
});

await Task.WhenAll(tasks);
sw.Stop();

Console.WriteLine($"Pipeline complete: {results.Count} QR codes from {files.Length} files in {sw.Elapsed.TotalSeconds:F1}s");
C#

Wynik

Po zakończeniu działania potoku konsola wyświetla podsumowanie: łączną liczbę zdekodowanych kodów QR, liczbę plików źródłowych i czas, który upłynął, a następnie nazwę każdego pliku i jego zdekodowany adres URL.

Wynik działania programu wyświetlany w terminalu: 20 kodów QR z 20 plików z odkodowanym adresem URL dla każdego pliku

Pobierz wszystkie 20 obrazów testowych z kodami QR (high-volume-qr-images.zip).

Dostosuj limit semaforów do dostępnej liczby rdzeni w celu uzyskania przepustowości lub zmniejsz go, gdy obciążenie pamięci stanowi problem w przypadku dużych obrazów.


Więcej informacji

Zapoznaj się z opcjami licencyjnymi, gdy potok będzie gotowy do produkcji.

Często Zadawane Pytania

Czym jest asynchroniczne przetwarzanie kodu QR w C#?

Asynchroniczne przetwarzanie kodu QR w C# pozwala wykonywać operacje kodu QR bez blokowania głównego wątku, wykorzystując funkcje takie jak metoda ReadAsync IronQR, aby poprawić wydajność i responsywność.

Jak wielowątkowość może zwiększyć wydajność przetwarzania kodu QR?

Wielowątkowość może znacznie zwiększyć wydajność przetwarzania kodu QR, umożliwiając jednoczesne uruchamianie wielu operacji, co umożliwia szybsze czasy przetwarzania i poprawioną efektywność aplikacji z wykorzystaniem IronQR.

Czym jest metoda ReadAsync w IronQR?

Metoda ReadAsync w IronQR umożliwia asynchroniczne czytanie kodów QR, pozwalając twojej aplikacji C# obsługiwać dane kodu QR bez opóźniania innych zadań.

W jaki sposób Parallel.ForEach pomaga w przetwarzaniu kodów QR?

Parallel.ForEach umożliwia jednoczesne przetwarzanie wielu kodów QR przez rozdzielanie zadań na wiele wątków, które można efektywnie wykorzystać z IronQR, aby przyspieszyć operacje kodów QR.

Jaką rolę odgrywa SemaphoreSlim w operacjach kodu QR?

SemaphoreSlim jest używane do ograniczania liczby współbieżnych zadań, co pomaga efektywnie zarządzać zasobami podczas przetwarzania równoległego kodów QR z IronQR.

Czy można użyć IronQR do przetwarzania kodów QR w ograniczonym potoku?

Tak, IronQR można użyć do przetwarzania kodów QR w ograniczonym potoku, korzystając z konstrukcji takich jak SemaphoreSlim, aby skutecznie kontrolować współbieżność i alokację zasobów.

Jakie są korzyści z używania IronQR do asynchronicznych operacji kodu QR?

Użycie IronQR do operacji asynchronicznych kodu QR poprawia responsywność aplikacji, zmniejsza blokowanie na głównym wątku i pozwala na efektywne obsługiwanie dużych ilości danych kodu QR.

Czy można uruchamiać operacje kodu QR równolegle za pomocą IronQR?

Tak, IronQR obsługuje przetwarzanie równoległe operacji kodu QR, pozwalając wykorzystać możliwości wielowątkowości w C# do szybszej i bardziej wydajnej obsługi kodów QR.

W jaki sposób IronQR zwiększa przetwarzanie kodów QR w aplikacjach C#?

IronQR zwiększa przetwarzanie kodów QR poprzez dostarczanie solidnych możliwości asynchronicznych i wielowątkowych, co zmniejsza czas przetwarzania i poprawia skalowalność aplikacji C#.

Jakie funkcje C# uzupełniają użycie IronQR do przetwarzania kodów QR?

Funkcje C# takie jak async/await, Parallel.ForEach i SemaphoreSlim uzupełniają IronQR, zapewniając ramy dla efektywnego i wydajnego przetwarzania kodów QR.

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podręczników.

...
Czytaj więcej

Gotowy, aby rozpocząć?

Nuget Downloads 74,386Wersja:2026.9właśnie wydany

Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta
Biblioteka C# NuGet dla plików PDF
Zainstaluj za pomocą NuGet

Wersja: 2026.9

PM > Install-Package IronQR
nuget.org/packages/IronQR/
  1. W Eksploratorze Rozwiązań, kliknij prawym przyciskiem Myszy na Odwołania, Zarządzaj pakietami NuGet
  2. Wybierz Przeglądaj i wyszukaj "IronQR"
  3. Wybierz pakiet i zainstaluj
DLL PDF dla C#
Pobierz DLL

Wersja: 2026.9

  1. Pobierz i rozpakuj IronQR do lokalizacji, takiej jak ~/Libs w katalogu Solution
  2. W Eksploratorze rozwiązań Visual Studio kliknij prawym przyciskiem myszy Odwołania. Wybierz Przeglądaj, "IronQR.dll"

Licencje od $999

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Zarezerwuj swoje darmowe Demo na żywo
Booking Badge

Zaufane przez miliony inżynierów na całym świecie

Logotypy klientów Iron Software
Otrzymaj swoje Konsultacja Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta