Microsoft MVP성태의 닷넷 이야기
.NET Framework: 1085. .NET 6에 포함된 신규 BCL API [링크 복사], [링크+제목 복사],
조회: 7718
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 1개 있습니다.)

.NET 6에 포함된 신규 BCL API

다음과 같은 좋은 소개 글이 있군요. ^^

A preview of all of the new runtime features added in .NET 6 
; https://threadreaderapp.com/thread/1422816504060416002.html

현재(2021-08-10) .NET 6 preview 6이 나온 상태이고, 위의 글에 소개된 기능들은 모두 테스트가 가능합니다. 그럼, 이참에 같이 따라 해 볼까요? ^^

우선, FileStream을 사용하지 않고 C++처럼 저수준의 Handle만으로 파일 연산을 할 수 있는 API가 추가되었습니다.

static void lowLevelFileOperation()
{
    using var handle = File.OpenHandle("ConsoleApp1.exe");
    var length = RandomAccess.GetLength(handle);
    Console.WriteLine($"FileLength: {length}");
}

그다음, "Process" 개체 생성 없이 현재 프로세스에 한해 경로와 id를 접근할 수 있는 속성이 Environment에 추가되었습니다.

static void getProcessInfoWihtoutProcessObject()
{
    var pid = Environment.ProcessId;
    var path = Environment.ProcessPath;

    Console.WriteLine($"ProcessId: {pid}");
    Console.WriteLine($"ProcessPath: {path}");
}

GC를 최소화하기 위한 눈물 겨운 노력으로 보입니다. ^^

CSPNG(Cryptographically Secure Pseudorandom Number Generator)의 사용법도 아주 단순한 유형으로 하나 제공합니다. 가령, 4바이트 무작위 정수를 반환받고 싶다면 이렇게 호출할 수 있습니다.

static void produceRandomInt4()
{
    var bytes = RandomNumberGenerator.GetBytes(4);
    Console.WriteLine($"Random Int4: {BitConverter.ToInt32(bytes)}");
}

Parallel.ForEachAsync도 추가되었습니다.

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);

    await Parallel.ForEachAsync(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");
        }
    });
}

IEnumerable<T> LINQ 확장 메서드에도 역시 도우미 메서드들이 많이 추가되었다고 합니다. 아래는 컬렉션의 개수를 특정 묶음으로 나누는 Chunk 메서드이고,

static void ImprovedLinqMethods()
{
    int chunkNumber = 1;

    foreach (int[] chunk in Enumerable.Range(0, 9).Chunk(4))
    {
        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
*/

새롭게 MaxBy, MinBy가 기존의 IEnumerable.Max/Min을 보완해 추가되었습니다.

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 }

보는 바와 같이, 기본형이 아닌 경우 Max/Min은 해당 인스턴스를 반환받고 싶다면 IComparer를 구현한 개체를 반환해야 했지만, MaxBy/MinBy는 비교할 멤버를 지정하면서도 개체를 결과로 반환해 주고 있습니다.

BitOperations에 추가된 IsPow2, RoundUpToPowerOf2 메서드는 그냥 추가되었다는 것만 기억해도 좋을 듯싶고,

static void testBitOperation()
{
    uint bufferSize = 235;
    if (!BitOperations.IsPow2(bufferSize))
    {
        bufferSize = BitOperations.RoundUpToPowerOf2(bufferSize);
    }

    Console.WriteLine(bufferSize); // 출력 결과 256
}

비동기 메서드 호출 시, 해당 작업이 특정 시간 내에 끝나지 않으면 예외를 발생시키도록 만드는 것은 기억해 둘 만하겠습니다.

static async Task WaitOnly10Sec()
{
    var task = Task.Run(() =>
    {
        return Task.Delay(5 * 1000);
    });

    // await task; // 원래는 5초를 대기해야 하지만,

    Console.WriteLine($"[start] Task.Run: {DateTime.Now}");
    await task.WaitAsync(TimeSpan.FromSeconds(2));
    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.
(String[] args) in ConsoleApp1.dll:token 0x600000e+0xc */




ASP.NET Core의 경우 Configuration.GetRequiredSection 메서드가 추가되어 필수 설정이 없는 경우 예외를 발생시키는 것을 지원합니다.

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.'
    Configuration.GetRequiredSection("MyOptions").Bind(options);

    services.AddControllers();
}

따라서, 이 오류로 인해 개발자는 명시적으로 해당 속성을 appsettings.json에 추가해야 한다는 것을 인지할 수 있습니다.

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*",
    "MyOptions": {
        "SettingValue":  "test_var_1",
    }
}

이와 함께, @OpenTelemetry 지원을 위한 API를 내장하게 되었습니다. 가령 아래의 예제는 ASP.NET Core Web API 프로젝트에 추가했기 때문에 Web API의 호출 수를 제공하게 됩니다.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseAuthorization();

    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);
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

(첨부 파일은 이 글의 예제 코드를 포함합니다.)




참고로, 원 글에서는 이 외에도 Preview 7에 포함된 3가지 기능도 함께 소개하고 있습니다.

Make improvements to signal handling on .NET applications
; https://github.com/dotnet/runtime/issues/50527

Implement NativeMemory #54006
; https://github.com/dotnet/runtime/pull/54006

Add ArgumentNullException.ThrowIfNull
; https://github.com/dotnet/runtime/pull/55594

기타!

Using the new PriorityQueue from .NET 6 (Preview 2)
; https://blog.elmah.io/using-the-new-priorityqueue-from-net-6/




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 8/19/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2021-08-27 01시32분
New .NET 6 APIs driven by the developer community
; https://devblogs.microsoft.com/dotnet/new-dotnet-6-apis-driven-by-the-developer-community/

해당 API들이 전부 외부 개발자 커뮤니티로부터 추가된 것이라고 합니다. ^^
정성태

... 31  32  33  34  35  36  37  38  39  40  [41]  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12614정성태4/24/20219849개발 환경 구성: 570. C# - Azure AD 인증을 지원하는 ASP.NET Core/5+ 웹 애플리케이션 예제 구성 [4]파일 다운로드1
12613정성태4/23/20218867.NET Framework: 1048. C# - ETW 이벤트의 Keywords에 속한 EventId 구하는 방법 (2) 관리 코드파일 다운로드1
12612정성태4/23/20219014.NET Framework: 1047. C# - ETW 이벤트의 Keywords에 속한 EventId 구하는 방법 (1) PInvoke파일 다운로드1
12611정성태4/22/20218219오류 유형: 711. 닷넷 EXE 실행 오류 - Mixed mode assembly is build against version 'v2.0.50727' of the runtime
12610정성태4/22/20218056.NET Framework: 1046. C# - 컴파일 시점에 참조할 수 없는 타입을 포함한 이벤트 핸들러를 Reflection을 이용해 구독하는 방법파일 다운로드1
12609정성태4/22/20219479.NET Framework: 1045. C# - 런타임 시점에 이벤트 핸들러를 만들어 Reflection을 이용해 구독하는 방법파일 다운로드1
12608정성태4/21/202110422.NET Framework: 1044. C# - Generic Host를 이용해 .NET 5로 리눅스 daemon 프로그램 만드는 방법 [9]파일 다운로드1
12607정성태4/21/20218955.NET Framework: 1043. C# - 실행 시점에 동적으로 Delegate 타입을 만드는 방법파일 다운로드1
12606정성태4/21/202113037.NET Framework: 1042. C# - enum 값을 int로 암시적(implicit) 형변환하는 방법? [2]파일 다운로드1
12605정성태4/18/20218972.NET Framework: 1041. C# - AssemblyID, ModuleID를 관리 코드에서 구하는 방법파일 다운로드1
12604정성태4/18/20217598VS.NET IDE: 163. 비주얼 스튜디오 속성 창의 "Build(빌드)" / "Configuration(구성)"에서의 "활성" 의미
12603정성태4/16/20218495VS.NET IDE: 162. 비주얼 스튜디오 - 상속받은 컨트롤이 디자인 창에서 지원되지 않는 문제
12602정성태4/16/20219697VS.NET IDE: 161. x64 DLL 프로젝트의 컨트롤이 Visual Studio의 Designer에서 보이지 않는 문제 [1]
12601정성태4/15/20218788.NET Framework: 1040. C# - REST API 대신 github 클라이언트 라이브러리를 통해 프로그래밍으로 접근
12600정성태4/15/20218945.NET Framework: 1039. C# - Kubeconfig의 token 설정 및 인증서 구성을 자동화하는 프로그램
12599정성태4/14/20219707.NET Framework: 1038. C# - 인증서 및 키 파일로부터 pfx/p12 파일을 생성하는 방법파일 다운로드1
12598정성태4/14/20219778.NET Framework: 1037. openssl의 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법 (2)파일 다운로드1
12597정성태4/13/20219860개발 환경 구성: 569. csproj의 내용을 공통 설정할 수 있는 Directory.Build.targets / Directory.Build.props 파일
12596정성태4/12/20219548개발 환경 구성: 568. Windows의 80 포트 점유를 해제하는 방법
12595정성태4/12/20218999.NET Framework: 1036. SQL 서버 - varbinary 타입에 대한 문자열의 CAST, CONVERT 변환을 C# 코드로 구현
12594정성태4/11/20218456.NET Framework: 1035. C# - kubectl 명령어 또는 REST API 대신 Kubernetes 클라이언트 라이브러리를 통해 프로그래밍으로 접근 [1]파일 다운로드1
12593정성태4/10/20219656개발 환경 구성: 567. Docker Desktop for Windows - kubectl proxy 없이 k8s 대시보드 접근 방법
12592정성태4/10/20219471개발 환경 구성: 566. Docker Desktop for Windows - k8s dashboard의 Kubeconfig 로그인 및 Skip 방법
12591정성태4/9/202112742.NET Framework: 1034. C# - byte 배열을 Hex(16진수) 문자열로 고속 변환하는 방법 [2]파일 다운로드1
12590정성태4/9/20219236.NET Framework: 1033. C# - .NET 4.0 이하에서 Console.IsInputRedirected 구현 [1]
12589정성태4/8/202110566.NET Framework: 1032. C# - Environment.OSVersion의 문제점 및 윈도우 운영체제의 버전을 구하는 다양한 방법 [1]
... 31  32  33  34  35  36  37  38  39  40  [41]  42  43  44  45  ...