이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 15343|회답: 2

[통신] [번역]. VALUETask와 Task의 차이를 사용하는 NET.

[링크 복사]
2022-3-17 11:21:50에 게시됨 | | | |


작업 또는 작업 클래스를 사용하는 것은 이전 글에서 언급하지 않은 성능 병목 현상이 있습니다. 요컨대, 이 수업들은 결과가 즉시 나올 때 주도권을 잡습니다불필요한 할당。 즉, 결과가 이미 제공되더라도 항상 새로운 작업 또는 작업 객체가 생성됩니다. 앞서 언급했듯이, 이전 기사에서 사용한 비동기/대기 개념은 .NET 4.5 릴리스부터 사용되어 왔습니다. 이 기능은 C# 7 이후 .NET 4.7 버전에서 비동기 함수의 반환 시 사용할 수 있는 ValueTask 구조를 통해 강화되었습니다.

ValueTask 구조


ValueTask 구조는 2015년 corefxlab 저장소에 처음 등장했습니다. 이 저장소는 메인 corefx 저장소에 들어갈 수도 있고 없을지도 모르는 새로운 아이디어를 실험하고 탐구하는 데 사용됩니다. Corefx 저장소는 모든 .NET Core 기본 라이브러리가 위치한 저장소입니다. 이 라이브러리는 Stephen Taub가 System.Threading.Tasks.Channels 라이브러리를 위해 개발하고 제안했습니다. 그때 스티븐은 간략한 설명을 했다:

coreFXlab 라이브러리 주소:하이퍼링크 로그인이 보입니다.


ValueTask는 T와 Task의 별개의 유니언으로, ReadAsync가 자유롭게 할당하여 사용 가능한 T 값을 동기적으로 반환할 수 있게 합니다(Task.FromResult는 Task 인스턴스 할당이 필요합니다). ValueTask는 대기 가능하므로 대부분의 인스턴스 소비와 작업 소비를 구분할 수 없습니다.
많은 사람들이 이 구조를 사용하는 이점을 보고 있는데, 이 구조는 System.Threading.Tasks.Extensions NuGet 패키지의 일부로 C# 7에 포함되어 있습니다. 따라서 ValueTask 구조에 들어가기 전에, 이 구조가 해결하는 데 사용되는 문제를 살펴보겠습니다. Task(Task)는 참조 유형이므로 다음으로 시작하세요비동기식 메서드가 작업 객체를 반환한다는 것은 작업 객체가 매번 힙에 할당된다는 의미입니다。 이는 많은 경우 필요합니다.

하지만 경우에 따라 비동기 메서드는 즉시 또는 동기식 완료로 결과를 반환하기도 합니다. 이 경우 이 할당은 불필요하며, 코드의 성능이 중요한 부분에서는 비용이 많이 들 수 있습니다. .NET 4.7 릴리스 이전까지는 비동기 메서드가 Task, Task, 또는 void를 반환해야 했기 때문에 이를 피할 방법이 없었습니다<T>(후자는 보통 바람직하지 않았습니다). 이 버전의 .NET에서는 이 기능이 확장되어 비동기 메서드가 접근 가능한 GetAwaiter 메서드만 있으면 어떤 타입도 반환할 수 있습니다. ValueTask는 이러한 유형의 구체적인 예이며, 이 릴리스에도 추가되었습니다.

corefx 저장소를 둘러보시면 ValueTask의 전체 구현을 볼 수 있습니다. 저희가 관심 있는 API 섹션은 다음과 같습니다:



ValueTask는 구조로서 동기 실행 시간 동안 메모리를 할당하지 않는 비동기식 메서드를 작성할 수 있게 해줍니다. 비동기/대기 개념의 API 일관성은 이런 방식으로 훼손되지 않습니다. 게다가 이 구조는 스스로 기다려 있어 사용하기 쉽습니다. 예를 들어, 다음과 같은 간단한 코드를 실행해 봅시다:

MultiplyAsync 메서드에서는 Task 사용을 피하고 단순 정수만 반환하려는 상황을 시뮬레이션하고 있습니다. 이것은 메서드의 if 문에서 이루어지며, 기본적으로 전달된 매개변수가 0인지 확인하는 것입니다. 문제는if 문장의 조건이 참이더라도, 위 코드는 Task 객체를 생성합니다。 이 문제를 이렇게 해결합니다:

ValueTask와 Task



앞서 언급했듯이, ValueTask를 사용하는 데는 두 가지 주요 이점이 있습니다:

  • 성능 향상
  • 구현 유연성 증가


그렇다면 성능 향상의 수치는 무엇일까요? 이 코드를 참고하세요:


이 코드를 실행하면 JIT 실행에 120ns가 걸립니다. 이제 Task를 ValueTask로 바꿔 보면:

JIT를 사용하면 실행 시간이 65ns가 됩니다. 물론 Task.Delay 때문에 동기식 실행이 이루어지지 않는 것은 사실이지만, 실행 시간은 개선되고 있습니다.

또 다른 이점은 실행 방식의 유연성이 증가한다는 점입니다. 이게 정확히 무슨 뜻일까요? 동기화되어야 할 비동기 인터페이스 구현은 Task.Run 또는 Task.FromResult를 사용하도록 강제가 됩니다. 물론, 이것이 앞서 논의한 성능 문제로 이어집니다. ValueTask를 사용할 때는 동기식 구현과 비동기식 구현 중 하나를 선택할 가능성이 더 높습니다. 이런 일이 발생하면 코드가 제대로 설계되지 않았을 수 있다는 신호일 수 있다는 점을 기억하세요.

예를 들어, 다음 인터페이스를 보십시오:


예를 들어 코드에서 이렇게 호출하고 싶다고 가정해 봅시다:

인터페이스에서 ValueTask를 사용하기 때문에 인터페이스 구현은 동기식 또는 비동기식일 수 있습니다. 이 이점은 동기화 동작을 처리하는 함수를 IThing에 추가하는 것을 사실상 건너뛰면 됩니다. 이렇게 하면 이 인터페이스를 훨씬 쉽게 사용할 수 있습니다. 위 인터페이스의 동기식 구현은 다음과 같습니다:

다음은 같은 인터페이스의 비동기식 구현입니다:

하지만 ValueTask를 사용하기 전에 몇 가지 절충점을 고려해야 합니다. 기본적으로 ValueTask를 사용해야 한다고 생각하기 쉽지만, 사실 그렇지 않습니다. 예를 들어, ValueTask는 결과 동기화가 가능할 때 불필요한 할당을 피하는 데 도움을 주지만, 두 개의 필드도 포함하고 있습니다.

여기서 사용하는 구조는 가치 유형과 그 모든 부담을 사용하는 것임을 기억하는 것이 중요합니다. 반면 Task는 단 하나의 필드만 가진 참조 유형입니다.ValueTask를 사용하면 더 많은 데이터를 처리하고 처리해야 합니다. 비동기 메서드에서 이러한 메서드가 대기된다면, 비동기 메서드는상태 기계는 더 커질 것입니다전체 구조를 저장하는 것은 보통 단일 참조를 저장하는 것보다 더 많은 공간이 필요하기 때문입니다.

그래서 마이크로소프트 측은 비동기식 메서드의 기본 반환 타입으로 Task나 Task를 권장하는 것입니다. 성능 분석 후에만 ValueTask로 전환하는 것을 고려해야 합니다.


요약

ValueTask는 .NET 4.7에서 도입된 구조로, .NET에서 비동기식 메서드를 사용할 수 있는 다양한 가능성을 제공합니다. 하지만 대가가 없는 것은 아닙니다. 이는 동기식으로 실행되는 성능에 중요한 메서드에 유용합니다. 이들을 통해 불필요한 객체를 할당하는 것을 피할 수 있습니다. 그럼에도 불구하고, 가치 유형으로서 보통 가치 유형이 가진 모든 문제점들이 있습니다. 따라서 우리는 이 구조에서 이익을 얻을 수 있지만, 주의해야 합니다.

원본 주소:하이퍼링크 로그인이 보입니다.




이전의:【실질적 행동】도커를 사용해 IPsec VPN 서버를 구축하세요
다음:라우팅 테이블 잠금을 피하려면 Cisco AnyConnect 대신 OpenConnect를 사용하세요
2022-3-18 22:21:57에 게시됨 |
다시 배우러 왔다.
2022-3-22 14:05:53에 게시됨 |
학습의 본질을 배우세요나쁘지 않아요
면책 조항:
Code Farmer Network에서 발행하는 모든 소프트웨어, 프로그래밍 자료 또는 기사는 학습 및 연구 목적으로만 사용됩니다; 위 내용은 상업적 또는 불법적인 목적으로 사용되지 않으며, 그렇지 않으면 모든 책임이 사용자에게 부담됩니다. 이 사이트의 정보는 인터넷에서 가져온 것이며, 저작권 분쟁은 이 사이트와는 관련이 없습니다. 위 내용은 다운로드 후 24시간 이내에 컴퓨터에서 완전히 삭제해야 합니다. 프로그램이 마음에 드신다면, 진짜 소프트웨어를 지원하고, 등록을 구매하며, 더 나은 진짜 서비스를 받아주세요. 침해가 있을 경우 이메일로 연락해 주시기 바랍니다.

Mail To:help@itsvse.com