C# 동시 프로그래밍·고전적인 예제 읽기 노트
서문
최근에 "C# 동시 프로그래밍·클래식 예제"라는 책을 읽었습니다. 이 책은 이론적인 책이 아니라 현재의 C#.NET을 더 잘 활용하는 방법을 주로 이야기하는 책입니다. 이러한 API는 우리에게 제공됩니다. 대부분의 책은 일상적인 개발에 자주 사용되는 예제입니다.
책에 나오는 일부 견해는 상당히 동의합니다. 예를 들어 저자는 현재 책의 대부분이 동시 멀티스레딩에 대한 내용을 마지막에 담고 있지만 동시 프로그래밍에 대한 소개 가이드와 참고 자료가 부족하다고 말했습니다. .
또 다른 관점은 국내 기술 인력의 대다수가 기술 수준이 낮을수록 강력하다고 믿는 반면, 상위 수준의 응용을 하는 사람들은 '코드 파머'라는 것이다. 사실 기존의 라이브러리를 잘 활용하는 것도 일종의 능력이다. 기본적인 지식을 이해하는 것도 일상생활에 도움이 되지만, 좀 더 높은 수준의 추상적인 개념을 배우는 것이 더 좋다.
비동기 기본
작업 일시 중지 및 최대 절전 모드
작업을 비동기적으로 일시 중지하거나 최대 절전 모드로 전환하려면 Task.Delay();
static async Task<T> DelayResult<T>(T result, TimeSpan delay) { await Task.Delay(delay); return result; }
비동기 재시도 메커니즘을 사용할 수 있습니다.
간단한 지수 백오프 전략으로, 재시도 시간이 점차 증가합니다. 이 전략은 일반적으로 웹 서비스에 액세스할 때 사용됩니다.
static async Task<string> DownloadString(string uri) { using (var client = new HttpClient()) { var nextDealy = TimeSpan.FromSeconds(1); for (int i = 0; i != 3; ++i) { try { return await client.GetStringAsync(uri); } catch { } await Task.Delay(nextDealy); nextDealy = nextDealy + nextDealy; } //最后重试一次,抛出出错信息 return await client.GetStringAsync(uri); } }
진행 상황 보고
비동기 작업에서는 작업 진행 상황을 표시해야 하는 경우가 많으며 IProcess
static async Task MyMethodAsync(IProgress<double> progress) { double precentComplete = 0; bool done = false; while (!done) { await Task.Delay(100); if (progress != null) { progress.Report(precentComplete); } precentComplete++; if (precentComplete == 100) { done = true; } } } public static void Main(string[] args) { Console.WriteLine("starting..."); var progress = new Progress<double>(); progress.ProgressChanged += (sender, e) => { Console.WriteLine(e); }; MyMethodAsync(progress).Wait(); Console.WriteLine("finished"); }
일괄 작업 대기
동시에 여러 작업을 수행하고 모두 완료될 때까지 기다립니다
Task task1 = Task.Delay(TimeSpan.FromSeconds(1)); Task task2 = Task.Delay(TimeSpan.FromSeconds(2)); Task task3 = Task.Delay(TimeSpan.FromSeconds(1)); Task.WhenAll(task1, task2, task3).Wait();
한 작업이 완료될 때까지 기다립니다
여러 작업을 수행하고 이 중 하나 완료에 대한 응답만 필요합니다. 주로 작업에 대해 여러 번의 독립적인 시도를 수행하는 데 사용됩니다. 시도 중 하나가 완료되면 작업이 완료됩니다.
static async Task<int> FirstResponseUrlAsync(string urlA, string urlB) { var httpClient = new HttpClient(); Task<byte[]> downloadTaskA = httpClient.GetByteArrayAsync(urlA); Task<byte[]> downloadTaskB = httpClient.GetByteArrayAsync(urlB); Task<byte[]> completedTask = await Task.WhenAny(downloadTaskA, downloadTaskB); byte[] data = await completedTask; return data.Length; }
컬렉션
불변 스택 및 큐
자주 수정되지 않고 여러 스레드에서 안전하게 액세스할 수 있는 스택 및 큐가 필요합니다. 해당 API는 Stack
내부 구현에서 객체를 덮어쓰면(재할당) 불변 컬렉션이 수정된 컬렉션을 반환하고 원래 컬렉션 참조는 변경되지 않습니다. 즉, 다른 변수가 동일한 것을 참조하는 경우. 객체(다른 변수)는 변경되지 않습니다.
ImmutableStack
var stack = ImmutableStack<int>.Empty; stack = stack.Push(11); var biggerstack = stack.Push(12); foreach (var item in biggerstack) { Console.WriteLine(item); } // output: 12 11 int lastItem; stack = stack.Pop(out lastItem); Console.WriteLine(lastItem); //output: 11
실제로 11을 저장하는 메모리는 두 스택 간에 내부적으로 공유됩니다. 이 구현은 매우 효율적이며 각 인스턴스는 스레드로부터 안전합니다.
ImmutableQueue
var queue = ImmutableQueue<int>.Empty; queue = queue.Enqueue(11); queue = queue.Enqueue(12); foreach (var item in queue) { Console.WriteLine(item); } // output: 11 12 int nextItem; queue = queue.Dequeue(out nextItem); Console.WriteLine(nextItem); //output: 11
불변 목록 및 컬렉션
ImmutableList
시간 복잡성
때로는 인덱싱을 지원하고 자주 수정되지 않으며 여러 스레드에서 안전하게 액세스할 수 있는 데이터 구조가 필요합니다.
var list = ImmutableList<int>.Empty; list = list.Insert(0, 11); list = list.Insert(0, 12); foreach (var item in list) { Console.WriteLine(item); } // 12 11
ImmutableList
ImmutableHashSet
때때로 이러한 데이터 구조가 필요합니다. 중복된 콘텐츠를 저장할 필요가 없고 자주 수정되지 않으며 여러 스레드에서 안전하게 액세스할 수 있습니다. 시간 복잡도 O(log N).
var set = ImmutableHashSet<int>.Empty; set = set.Add(11); set = set.Add(12); foreach (var item in set) { Console.WriteLine(item); } // 11 12 顺序不定
스레드로부터 안전한 사전
스레드로부터 안전한 키-값 쌍 컬렉션인 다중 스레드는 읽고 쓸 때 여전히 동기화를 유지할 수 있습니다.
ConcurrentDictionary
는 세분화된 잠금 기술과 잠금 없는 기술을 혼합하여 사용하며 가장 실용적인 컬렉션 유형 중 하나입니다.
var dictionary = new ConcurrentDictionary<int, string>(); dictionary.AddOrUpdate(0, key => "Zero", (key, oldValue) => "Zero");
여러 스레드가 공유 컬렉션을 읽고 쓰는 경우 ConcurrentDictionary
데이터를 공유해야 하는 상황, 즉 여러 스레드가 컬렉션을 공유하는 경우에 가장 적합합니다. 일부 스레드는 요소를 추가만 하고 일부 스레드는 요소를 제거만 하는 경우 생산자/소비자를 사용하는 것이 가장 좋습니다. 컬렉션(BlockingCollection
공유 리소스 초기화
프로그램은 여러 위치에서 값을 사용하고 처음 액세스할 때 초기화합니다.
static int _simpleVluae; static readonly Lazy<Task<int>> shardAsyncInteger = new Lazy<Task<int>>(async () => { await Task.Delay(2000).ConfigureAwait(false); return _simpleVluae++; }); public static void Main(string[] args) { int shareValue = shardAsyncInteger.Value.Result; Console.WriteLine(shareValue); // 0 shareValue = shardAsyncInteger.Value.Result; Console.WriteLine(shareValue); // 0 shareValue = shardAsyncInteger.Value.Result; Console.WriteLine(shareValue); // 0 }
위 내용은 C# 동시 프로그래밍·고전 예제 읽기 노트 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











C#을 사용한 Active Directory 가이드. 여기에서는 소개와 구문 및 예제와 함께 C#에서 Active Directory가 작동하는 방식에 대해 설명합니다.

C#의 난수 생성기 가이드입니다. 여기서는 난수 생성기의 작동 방식, 의사 난수 및 보안 숫자의 개념에 대해 설명합니다.

C# 데이터 그리드 뷰 가이드. 여기서는 SQL 데이터베이스 또는 Excel 파일에서 데이터 그리드 보기를 로드하고 내보내는 방법에 대한 예를 설명합니다.

멀티 스레딩과 비동기식의 차이점은 멀티 스레딩이 동시에 여러 스레드를 실행하는 반면, 현재 스레드를 차단하지 않고 비동기식으로 작업을 수행한다는 것입니다. 멀티 스레딩은 컴퓨팅 집약적 인 작업에 사용되며 비동기식은 사용자 상호 작용에 사용됩니다. 멀티 스레딩의 장점은 컴퓨팅 성능을 향상시키는 것이지만 비동기의 장점은 UI 스레드를 차단하지 않는 것입니다. 멀티 스레딩 또는 비동기식을 선택하는 것은 작업의 특성에 따라 다릅니다. 계산 집약적 작업은 멀티 스레딩을 사용하고 외부 리소스와 상호 작용하고 UI 응답 성을 비동기식으로 유지 해야하는 작업을 사용합니다.
