성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET 6에 포함된 신규 BCL API - 스레드 관련</h1> <p> 다음과 같은 좋은 소개 글이 있군요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET 6: Threading Improvements ; <a target='tab' href='https://www.infoq.com/news/2021/08/net6-Threading/'>https://www.infoq.com/news/2021/08/net6-Threading/</a> </pre> <br /> <br /> 마음대로 정리해 보겠습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <a name='parallel'></a> <br /> 기존에 Parallel.For, Parallel.ForEach도 꽤 쓸만(<a target='tab' href='https://www.sysnet.pe.kr/2/0/12290#parallel_foreach'>사례 1</a>, <a target='tab' href='https://www.sysnet.pe.kr/2/0/11423#parallel_for'>사례 2</a>, <a target='tab' href='https://www.sysnet.pe.kr/2/0/1293#parallel_for'>사례 3</a>) 했는데요, .NET 6부터 Parallel.ForEachAsync도 추가했습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask> body) public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, CancellationToken cancellationToken, Func<TSource, CancellationToken, ValueTask> body) public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TSource, CancellationToken, ValueTask> body) public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask> body) public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken, Func<TSource, CancellationToken, ValueTask> body) public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TSource, CancellationToken, ValueTask> body) </pre> <br /> 사실 이에 대해서는 이전 글에서도,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET 6에 포함된 신규 BCL API ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12768#parallel_foreach_async'>https://www.sysnet.pe.kr/2/0/127688#parallel_foreach_async</a> </pre> <br /> 이미 소개를 했습니다. 단지, ValueTask에 대한 버전이 추가되었다는 정도는 인식하면 좋겠습니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> Thread.ManagedThreadId가 deprecated 되었습니다. 문득 2007년에 썼던 글이 생각나는군요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ManagedThreadId ? ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/491'>https://www.sysnet.pe.kr/2/0/491</a> ManagedThreadId - 두 번째 이야기 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/492'>https://www.sysnet.pe.kr/2/0/492</a> </pre> <br /> 당시에 AppDomain.GetCurrentThreadId() API가 이미 deprecated 상태였는데 아직까지도 잘 쓰이고 있는 상황에서 Thread.ManagedThreadId를 추가로 deprecated 시킨 것이 좀 뜻밖입니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Console.WriteLine(Thread.CurrentThread.ManagedThreadId); Console.WriteLine(Environment.CurrentManagedThreadId); </pre> <br /> 대신, .NET 4.5부터 제공하던 <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.environment.currentmanagedthreadid'>Environment.CurrentManagedThreadId</a>가 있으니 앞으로는 이것을 활용하라고 조언하고 있는데요.<br /> <br /> 재미있는 것은, 지침 자체는 deprecated라고는 하지만 실제 API 코드에는 [Obsolete] 특성이 명시되지 않았다고 합니다. 게다가 이건 좀 지켜봐야 할 필요가 있는데, 현재 .NET 6 Preview 7 단계의 Visual Studio 2022 Preview 3.0에서도 아직 정적 분석기에 의한 deprecated 표시가 되지 않고 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 스레드 실행 문맥 관련한 글을 예전에 썼는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > HttpContext.Current를 통해 이해하는 CallContext와 ExecutionContext ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/1608'>https://www.sysnet.pe.kr/2/0/1608</a> HttpContextAccessor를 통해 이해하는 AsyncLocal<T> ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12467'>https://www.sysnet.pe.kr/2/0/12467</a> C# - AsyncLocal 기능을 CallContext만으로 구현하는 방법 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12706'>https://www.sysnet.pe.kr/2/0/12706</a> ASP.NET의 HttpContext.Current 구현에 대응하는 ASP.NET Core의 IHttpContextAccessor/HttpContextAccessor 사용법 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/11440'>https://www.sysnet.pe.kr/2/0/11440</a> </pre> <br /> 또한, 스레드 실행 문맥을 무시하는 ThreadPool의 예제와 ExecutionContext의 SuppressFlow/RestoreFlow를 예로 들었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // QueueUserWorkItem과는 달리 실행 문맥 무시 ThreadPool.<span style='color: blue; font-weight: bold'>Unsafe</span>QueueUserWorkItem(threadFunc, null); // QueueUserWorkItem을 사용해도 SuppressFlow를 사용해 실행 문맥 무시 ExecutionContext.<span style='color: blue; font-weight: bold'>SuppressFlow</span>(); ThreadPool.QueueUserWorkItem(threadFunc, null); ExecutionContext.<span style='color: blue; font-weight: bold'>RestoreFlow</span>(); </pre> <br /> 이러한 실행 문맥 무시를 Thread.Start의 버전에서도 "Thread.<span style='color: blue; font-weight: bold'>Unsafe</span>Start"라는 이름으로 제공합니다. <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Thread.UnsafeStart Method ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.unsafestart'>https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.unsafestart</a> </pre> <br /> 현재 이 API는 다음의 경우에 사용된다고 합니다.<br /> <br /> <ul> <li>FileSystemWatcher for OS X</li> <li>SocketAsyncEngine for Unix</li> <li>CounterGroup in the Tracing APIs</li> <li>ThreadPoolTaskScheduler when the task is marked as LongRunning</li> </ul> <br /> <hr style='width: 50%' /><br /> <br /> 신규 타이머 기능으로 (기획 단계에서 <a target='tab' href='https://github.com/dotnet/runtime/issues/31525'>AsyncTimer</a>라고 불리던) <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.threading.periodictimer'>PeriodicTimer 타입</a>이 추가됐습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var second = TimeSpan.FromSeconds(1); using var timer = new PeriodicTimer(second); while (await timer.WaitForNextTickAsync()) { Console.WriteLine($"Tick {DateTime.Now}"); } /* 출력 결과 Tick 2021-08-19 오후 10:42:31 Tick 2021-08-19 오후 10:42:32 Tick 2021-08-19 오후 10:42:33 Tick 2021-08-19 오후 10:42:34 ...[무한 루프]... */ </pre> <br /> 말 그대로 비동기 타이머 기능을 제공하는군요. ^^ 기존에도 Task.Delay로 유사하게 구현할 수 있었는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > while (true) { await Task.Delay(1000); Console.WriteLine($"Tick {DateTime.Now}"); } </pre> <br /> 특이하게 PeriodicTimer는 (어떻게 재현해야 하는지는 알 수 없으나) 사용자 코드가 실행 중이면 발생하지 않는다고 합니다. 또한, (Thread.UnsafeStart에서 설명한) 실행 문맥도 캡처하지 않는다고.<br /> <br /> 가뜩이나 많은 타이머의 홍수 속에,<br /> <br /> <ul> <li>System.Timers.Timer</li> <li>System.Threading.Timer</li> <li>System.Windows.Forms.Timer</li> <li>System.Web.UI.Timer</li> <li>System.Windows.Threading.DispatcherTimer</li> </ul> <br /> 어떤 타이머를 선택할지에 대한 가이드 문서를 올릴 예정이라고 합니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1328
(왼쪽의 숫자를 입력해야 합니다.)