C\#Task.Yeild()함수 에 대한 토론

3656 단어 C#Task.Yeild()함수.
동료 와 async/await 내부 실현 에 대해 토론 할 때 갑자기 Task.Yeild()라 는 함수 가 생각 났 습 니 다.왜 일 까요?이 유 는 스 레 드 전환 을 피 하 는 것 입 니 다.await 뒷부분 의 코드 는 다른 스 레 드 로 실 행 될 수 있 기 때 문 입 니 다.Task.Yeild()는 호출 자 에 게 강제로 돌아 가 거나 실행 권 을 자발적으로 양보 하여 다른 Task 에 게 실 행 될 기 회 를 줄 수 있 기 때 문 입 니 다.Task.Yeild()와 Thread.sleep(0)는 약간 같 습 니 다.
      나의 결론 이 성립 되 었 다 는 것 을 증명 하기 위해 서 코드 를 보십시오.

public static async Task Test1()
{
   await Task.CompletedTask;
   Thread.Sleep(1000);
   Console.WriteLine("Test1    ");
}
public static async Task Test2()
{
   await Task.Delay(1);
   Thread.Sleep(1000);
   Console.WriteLine("Test2    ");
}
public static async Task Test3()
{
   await Task.Yield();
   Thread.Sleep(1000);
   Console.WriteLine("Test3    ");
}
static void Main(string[] args)
{
   Console.WriteLine(DateTime.Now);
   _ = Test1();
   Console.WriteLine(DateTime.Now);
   Console.ReadLine();
}
      시작 이론 에 따 르 면 Test 1()비동기 함 수 는 await 가 이미 완 성 된 임 무 를 수행 하기 때문에 계속 아래로 실행 하고 1 초 동안 막 은 다음 에 호출 자 에 게 돌아 가 인쇄 하 는 시간 차 이 는 1 초 입 니 다.

      Test 2()비동기 함 수 는 await 가 완료 되 지 않 은 작업(1ms 는 CPU 에 있어 서 매우 긴 것)을 했 기 때문에 호출 자 에 게 돌아 가서 같은 시간 을 인쇄 하고 1 초 후에 인쇄 가 실 행 됩 니 다.

      Test 3()는 Task.Yeild()함 수 를 호출 하여 실행 권 을 주동 적 으로 내 주 었 기 때문에 호출 자 에 게 직접 돌아 가서 같은 시간 을 인쇄 하고 1 초 후에 인쇄 가 완 료 됩 니 다.

      첫머리 의 결론 이 정확 하 다 는 것 을 알 수 있다.그렇다면 무슨 의미 가 있 을 까?Yeild 의 뜻 은 여기 서 양보,양보 라 는 뜻 입 니 다.무엇 을 양보 하 시 겠 습 니까?실행 권 을 내 주 는 것 은 Thread.sleep(0)이 CPU 실행 권 을 다른 스 레 드(다른 스 레 드 경쟁 이 있 는 전제)에 게 내 주 는 것 과 일리 가 있다.
      제 예 를 보 세 요.

public static async Task OP1()
{
   while (true)
   {
     await Task.Yield();//          ,        ,       ,                    
                   //                  ,              1,           ,    
                   //        
     Console.WriteLine("OP1   ");
     Thread.Sleep(1000);//        CPU   
   }
}
public static async Task OP2()
{
   while (true)
   {
     await Task.Yield();
     Console.WriteLine("OP2   ");
     Thread.Sleep(1000);
   }
}
static async Task Main(string[] args)
{
   ThreadPool.SetMinThreads(1, 1);
   ThreadPool.SetMaxThreads(1, 1);
   //Task.Run()                  ,            ,    Task.Run()
   var t = Task.Run(async () =>
   {
     var t1 = OP1();
     var t2 = OP2();
     await Task.WhenAll(t1, t2);
   });
   await t;
   Console.ReadLine();
}

      OP1()과 OP2()두 협상(Task)이 서로 한 스 레 드(사용자 모드 에서 의 CPU)를 다 투 는 것 을 알 수 있 고,실행 권 을 주동 적 으로 내주 지 않 으 면 다른 협상(Task)이 실행 할 기회 가 없 을 것 이다.
      예 를 들 면:

public static async Task OP2()
{
   while (true)
   {
     await Task.CompletedTask;//       
     Console.WriteLine($"OP2    {DateTime.Now}");
     Thread.Sleep(1000);
   }
}
      이렇게 하면 OP1()은 영원히 집행 할 기회 가 없 을 것 이다.

이상 은 C\#에서 Task.Yeild()함수 에 대한 토론 의 상세 한 내용 입 니 다.C\#Task.Yeild()에 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기