비동기식 C#: 위쪽 체리🍒 (힌트와 팁)
안전벨트를 매다🚀..
✔ 힌트 1
static async Task BoilWaterAsync()
{
Console.WriteLine("Starting the kettle");
await Task.Delay(3000);
Console.WriteLine("Kettle Finished Boiling");
}
static async Task PourWaterAsync()
{
var boilWaterTask = BoilWaterAsync();
await boilWaterTask;
Console.WriteLine("Pouring boiling water.");
}
static async Task Main(string[] args)
{
// Notice we are not awaiting the task!
PourWaterAsync();
Console.WriteLine("Program Ended");
}
우리의 첫 번째 예에서 PourWaterAsync()
는 Task
기다리지 않은 임무를 나타낸다. 비록 이 임무는 기다리고 있는 내부 임무로 구성되어 있지만.이 예제를 실행하면 다음과 같은 출력이 발생합니다.
Starting the kettle
Program Ended
임무Task.Delay(3000)
가 시작되었지만 기다림에도 불구하고 종점선에 도착하지 않았고 주전자도 끓지 않았다.이 동작은 최고급
await
함수에서 Main()
키워드를 건너뛰었기 때문에 발생합니다.물론 이 두 줄을 다시 써라.
var boilWaterTask = BoilWaterAsync();
await boilWaterTask;
다음이 됩니다.await BoilWaterAsync();
같은 결과를 얻게 될 것이다.마지막 호출점에 도착할 때까지 모든 작업을 기다립니다.
✔ 힌트
public void Main(string[]args)
{
var task = BoilWaterAsync();
// DON'T
var result = task.Result;
// A NO-NO
task.Wait();
// PLEASE DON'T ⛔
task.GetAwaiter().GetResult();
}
상기 세 가지 주의사항은 프로그램의 주 라인이 막힐 것입니다. 작업이 끝날 때까지 프로그램은 새로운 요청에 대한 응답을 멈추거나 동기화가 끝날 때까지 기다릴 수 있습니다.✅ 만들다
작업의 비동기성을 받아들이고 결과를 되돌려줍니다.코드에서 전파되는 임무는 정상적인 것이기 때문에 가능한 한 늦추면 된다.
✔ 프롬프트 #3
만약 우리가 인터페이스를 실현하고 있다면, 그 방법은 임무를 되돌려야 하지만, 이 방법 자체의 실행은 비동기적인 설정이 필요하지 않고, 주 라인을 막지 않으며, 동시에 실행할 수 있어 문제가 발생하지 않을 것이다.
interface MyInterface
{
Task<string> DoSomethingAndReturnAString();
}
class MyClass : MyInterface
{
public Task<string> DoSomethingAndReturnAString()
{
// Some logic that does not need the await keyword
return "result"; // Of course a compiler error, expecting Task<string> not a string
}
}
우리는 두 가지 방법으로 이 문제를 해결할 수 있다.솔루션 1 (최악)👎):
방법을
async
(우리가 아무것도 기다릴 필요가 없어도) 로 바꾸면 문자열을 정상적으로 되돌릴 수 있습니다. 그렇습니까?영원히 그렇게 하지 마!방법을
async
로 표시할 때, 컴파일러는 코드를 상태기로 변환합니다. 예를 들어 대기할 때 실행되고, 백엔드 작업이 끝난 후에 실행을 재개하는 등 몇 가지 일을 추적합니다.실제로, 방법을 async
로 표시한 후에 코드가 생성한 IL (중간 언어) 을 검사하면, 이 함수가 완전한 클래스가 되었다는 것을 알 수 있습니다.따라서 async(내부 대기 없음)로 표시된 동기화 방법에서도 상태기는 어떤 방식으로든 생성되며 더 빠른 속도로 내연되고 실행될 수 있는 코드는 상태기 관리에 추가적인 복잡성을 가져올 수 있다.
📝 이것이 바로 내부에wait만 존재할 때 방법을 비동기적으로 표시하는 것이 매우 중요한 이유이다.
솔루션 2(우수👍):
대신:
return Task.FromResult("result");
다시 한 번 예를 들자.외부 네트워크 소스에서 일부 텍스트를 검색하는 HTTP 클라이언트가 있습니다.
public Task<string> GetFromWebsite()
{
var client = new HttpClient();
var content = client.GetStringAsync("my.website.com");
•••
}
만약 목표가 웹 사이트에서 문자열을 검색하기 시작했을 뿐이라면 가장 좋은 방법은 원래 상태로 되돌아오는 GetStringAsync()
작업입니다. 여기서 기다리지 마십시오. 이것은 목적 없이 상태기를 만드는 것을 건너뛰는 것과 같은 원인으로 귀결됩니다.public Task<string> GetFromWebsite()
{
var client = new HttpClient();
return client.GetStringAsync("my.website.com");
}
호출을 기다리려는 유일한 시나리오는 메소드 내의 결과에 대해 로직을 수행하려는 것입니다.// Notice that we marked the method as async
public async Task<string> GetFromWebsiteAndValidate()
{
var client = new HttpClient();
var result = await client.GetStringAsync("my.website.com");
// Perform some logic on the result
return result;
}
만약 당신이 방법의 기능을 묘사할 때 'and' 라는 단어를 사용한다면, 어떤 부분은 옳지 않을 수도 있다는 것을 기억해라.예:
이것은 경험의 법칙이다👍 참고:
임무의 결과가 절대적으로 필요할 때만 기다린다.
async 키워드는 서로 다른 라인에서 이 방법을 실행하지 않으며, 다른 종류의 숨겨진 마법도 실행하지 않기 때문에, 방법에서 키워드wait를 사용해야 할 때만 이 방법을 async로 표시합니다.
기억해야 할 몇 가지 주의 사항:
void
, Task
또는 Task<T>
.Task
또는 하나Task<T>
로 되돌아오는 것이지 async
로 표시되기 때문에 우리는 await
비동기적인 함수Task
를 되돌아갈 수 있다.await
를 되돌릴 수 없습니다. void
함수는 되돌려 주지 않을 절대적인 이유가 없거나Task
함수 호출자가 무효 형식을 되돌려 주기를 원하지 않거나 함수 자체가 최고급 함수이기 때문에 다른 함수는 호출할 수 없습니다.✔ 힌트
긴 시간 동안 실행되는 작업은 항상 비동기적으로 실행되어야 하며, 이러한 작업은 입출력 제한과 CPU 제한의 두 종류로 나눌 수 있습니다.입출력 작업이 완료될 때까지 대기하는 데 걸리는 시간에 따라 작업이 완료되는 데 걸리는 시간이 주로 달라질 때 작업을 입출력 제한이라고 합니다.이에 비해 CPU 제한 작업의 완료 시간은 주로 중앙 프로세서의 속도에 따라 달라집니다. 예를 들어 다음과 같습니다.
Task
이나 Task<T>
이 있을 때await
는 async
방법으로 바인딩합니다.CPU가 바인딩된 코드의 경우 백그라운드 스레드 Task.Run
방법을 사용하여 시작할 때까지 기다려야 합니다.메모📝:
CPU 바인딩 코드의 실행 상황을 분석하고 다중 스레드 처리 시 상하문 전환 비용을 주의해야 합니다. 비교적 비싸지 않을 수도 있습니다.
자, 이것이 바로 내가 오늘 너희들에게 줄 것이다.
계속 인코딩😉
Reference
이 문제에 관하여(비동기식 C#: 위쪽 체리🍒 (힌트와 팁)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/paulafahmy/asynchronous-c-cherry-on-the-top-tips-and-tricks-4eod텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)