성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
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;' > A preview of all of the new runtime features added in .NET 6 ; <a target='tab' href='https://threadreaderapp.com/thread/1422816504060416002.html'>https://threadreaderapp.com/thread/1422816504060416002.html</a> </pre> <br /> 현재(2021-08-10) <a target='tab' href='https://dotnet.microsoft.com/download/dotnet/6.0'>.NET 6 preview 6이 나온 상태</a>이고, 위의 글에 소개된 기능들은 모두 테스트가 가능합니다. 그럼, 이참에 같이 따라 해 볼까요? ^^<br /> <br /> 우선, FileStream을 사용하지 않고 C++처럼 저수준의 Handle만으로 파일 연산을 할 수 있는 API가 추가되었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void lowLevelFileOperation() { using var handle = <span style='color: blue; font-weight: bold'>File.OpenHandle</span>("ConsoleApp1.exe"); var length = <span style='color: blue; font-weight: bold'>RandomAccess.GetLength</span>(handle); Console.WriteLine($"FileLength: {length}"); } </pre> <br /> 그다음, "Process" 개체 생성 없이 현재 프로세스에 한해 경로와 id를 접근할 수 있는 속성이 Environment에 추가되었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void getProcessInfoWihtoutProcessObject() { var pid = <span style='color: blue; font-weight: bold'>Environment.ProcessId</span>; var path = <span style='color: blue; font-weight: bold'>Environment.ProcessPath</span>; Console.WriteLine($"ProcessId: {pid}"); Console.WriteLine($"ProcessPath: {path}"); } </pre> <br /> GC를 최소화하기 위한 눈물 겨운 노력으로 보입니다. ^^<br /> <br /> CSPNG(Cryptographically Secure Pseudorandom Number Generator)의 사용법도 아주 단순한 유형으로 하나 제공합니다. 가령, 4바이트 무작위 정수를 반환받고 싶다면 이렇게 호출할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void produceRandomInt4() { var bytes = <span style='color: blue; font-weight: bold'>RandomNumberGenerator.GetBytes</span>(4); Console.WriteLine($"Random Int4: {BitConverter.ToInt32(bytes)}"); } </pre> <a name='parallel_foreach_async'></a> <br /> 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;' > static async Task parallelDownload() { var urlsToDownload = new[] { "https://www.bing.com", "https://www.google.com", "https://search.yahoo.com/" }; var client = new HttpClient(); // https://stackoverflow.com/questions/146134/how-to-remove-illegal-characters-from-path-and-filenames string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); var path = Path.GetDirectoryName(Environment.ProcessPath); <span style='color: blue; font-weight: bold'>await Parallel.ForEachAsync</span>(urlsToDownload, async (url, token) => { Regex r = new Regex(string.Format("[{0}]", Regex.Escape(invalidChars))); var targetPath = Path.Combine(path, r.Replace(url, "_") + ".txt"); var response = await client.GetAsync(url); if (response.IsSuccessStatusCode) { using var target = File.OpenWrite(targetPath); await response.Content.CopyToAsync(target); Console.WriteLine($"{targetPath}: downloaded"); } }); } </pre> <br /> IEnumerable<T> LINQ 확장 메서드에도 역시 도우미 메서드들이 많이 추가되었다고 합니다. 아래는 컬렉션의 개수를 특정 묶음으로 나누는 Chunk 메서드이고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void ImprovedLinqMethods() { int chunkNumber = 1; foreach (int[] chunk in Enumerable.Range(0, 9)<span style='color: blue; font-weight: bold'>.Chunk(4)</span>) { Console.WriteLine($"Chunk {chunkNumber++}"); foreach (var item in chunk) { Console.WriteLine(item); } } } /* 출력 결과 Chunk 1 0 1 2 3 Chunk 2 4 5 6 7 Chunk 3 8 */ </pre> <br /> 새롭게 MaxBy, MinBy가 기존의 IEnumerable.Max/Min을 보완해 추가되었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var people = new People[] { new People{ Name = "tester", Age = 30 }, new People{ Name = "admin", Age = 25 }, }; Console.WriteLine(people.Max((elem) => elem.Age)); // 출력 결과: 30 Console.WriteLine(people.Max(new AgeComparer())); // 출력 결과: People { Name = tester, Age = 30 } Console.WriteLine(people.MaxBy((elem) => elem.Age)); // 출력 결과: People { Name = tester, Age = 30 } Console.WriteLine(people.MinBy((elem) => elem.Age)); // 출력 결과: People { Name = tester, Age = 30 } </pre> <br /> 보는 바와 같이, 기본형이 아닌 경우 Max/Min은 해당 인스턴스를 반환받고 싶다면 IComparer를 구현한 개체를 반환해야 했지만, MaxBy/MinBy는 비교할 멤버를 지정하면서도 개체를 결과로 반환해 주고 있습니다.<br /> <br /> BitOperations에 추가된 <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/system.numerics.bitoperations.ispow2'>IsPow2</a>, <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/system.numerics.bitoperations.rounduptopowerof2'>RoundUpToPowerOf2</a> 메서드는 그냥 추가되었다는 것만 기억해도 좋을 듯싶고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void testBitOperation() { uint bufferSize = 235; if (!<span style='color: blue; font-weight: bold'>BitOperations.IsPow2</span>(bufferSize)) { bufferSize = <span style='color: blue; font-weight: bold'>BitOperations.RoundUpToPowerOf2</span>(bufferSize); } Console.WriteLine(bufferSize); // 출력 결과 256 } </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;' > static async Task WaitOnly10Sec() { var task = Task.Run(() => { return Task.Delay(5 * 1000); }); // await task; // 원래는 5초를 대기해야 하지만, Console.WriteLine($"[start] Task.Run: {DateTime.Now}"); <span style='color: blue; font-weight: bold'>await task.WaitAsync(TimeSpan.FromSeconds(2));</span> Console.WriteLine($"[end] Task.Run: {DateTime.Now}"); } /* 실행 결과: 2초가 지나 예외 발생 [start] Task.Run: 2021-08-08 오후 10:54:05 Unhandled exception. System.TimeoutException: The operation has timed out. at ConsoleApp1.Program.WaitOnly10Sec() at ConsoleApp1.Program.Main(String[] args) at ConsoleApp1.Program.<Main>(String[] args) in ConsoleApp1.dll:token 0x600000e+0xc */ </pre> <br /> <hr style='width: 50%' /><br /> <br /> ASP.NET Core의 경우 <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationextensions.getrequiredsection'>Configuration.GetRequiredSection</a> 메서드가 추가되어 필수 설정이 없는 경우 예외를 발생시키는 것을 지원합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public IConfiguration Configuration { get; } class MyOptions { public string? SettingValue { get; set; } } public void ConfigureServices(IServiceCollection services) { var options = new MyOptions(); // 추가된 appsettings.json에 "MyOptions"가 없는 경우 예외 발생 // System.InvalidOperationException: 'Section 'MyOptions' not found in configuration.' <span style='color: blue; font-weight: bold'>Configuration.GetRequiredSection("MyOptions").Bind(options);</span> services.AddControllers(); } </pre> <br /> 따라서, 이 오류로 인해 개발자는 명시적으로 해당 속성을 appsettings.json에 추가해야 한다는 것을 인지할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", <span style='color: blue; font-weight: bold'>"MyOptions": { "SettingValue": "test_var_1", }</span> } </pre> <br /> 이와 함께, <a target='tab' href='https://twitter.com/opentelemetry'>@OpenTelemetry</a> 지원을 위한 API를 내장하게 되었습니다. 가령 아래의 예제는 ASP.NET Core Web API 프로젝트에 추가했기 때문에 Web API의 호출 수를 제공하게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); <span style='color: blue; font-weight: bold'>var meter = new Meter("Microsoft.AspnetCore", "v1.0"); Counter<int> counter = meter.CreateCounter<int>("Requests"); app.Use((context, next) => { counter.Add(1, KeyValuePair.Create<string, object?>("path", context.Request.Path.ToString())); return next(context); });</span> app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1838&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, <a target='tab' href='https://threadreaderapp.com/thread/1422816504060416002.html'>원 글</a>에서는 이 외에도 Preview 7에 포함된 3가지 기능도 함께 소개하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Make improvements to signal handling on .NET applications ; <a target='tab' href='https://github.com/dotnet/runtime/issues/50527'>https://github.com/dotnet/runtime/issues/50527</a> Implement NativeMemory #54006 ; <a target='tab' href='https://github.com/dotnet/runtime/pull/54006'>https://github.com/dotnet/runtime/pull/54006</a> Add ArgumentNullException.ThrowIfNull ; <a target='tab' href='https://github.com/dotnet/runtime/pull/55594'>https://github.com/dotnet/runtime/pull/55594</a> </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;' > Using the new PriorityQueue from .NET 6 (Preview 2) ; <a target='tab' href='https://blog.elmah.io/using-the-new-priorityqueue-from-net-6/'>https://blog.elmah.io/using-the-new-priorityqueue-from-net-6/</a> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1672
(왼쪽의 숫자를 입력해야 합니다.)