C\#병렬 및 다 중 스 레 드 프로 그래 밍―Task 인식 및 사용

다 중 스 레 드 에 대해 서 는 Thread 를 자주 사용 합 니 다.우리 가 Task 를 이해 하기 전에 만약 에 우리 가 다 핵 기능 을 사용 하려 면 스스로 스 레 드 를 열 수 있 습 니 다.그러나 이런 스 레 드 모델 은.net 4.0 이후 에'작업 을 바탕 으로 하 는 프로 그래 밍 모델'이 라 고 불 리 는 충격 을 받 았 습 니 다.task 는 thread 보다 더 작은 성능 을 가지 기 때문에 여러분 들 은 의심 할 것 입 니 다.작업 과 스 레 드 는 도대체 어떤 차이 가 있 습 니까?
 작업 과 스 레 드 의 차이:
1.임 무 는 라인 위 에 구 축 된 것 이다.즉,임 무 는 결국 라인 에 던 져 서 집행 해 야 한다.
2.임무 와 스 레 드 는 일대일 관계 가 아니다.예 를 들 어 10 개의 임 무 를 수행 하 는 것 은 10 개의 스 레 드 를 운영 하 는 것 이 아니 라 이 임 무 는 스 레 드 풀 과 유사 하지만 임 무 는 스 레 드 풀 에 비해 적은 비용 과 정확 한 통 제 를 가진다.
 1.Task 와 Task 의 기본 사용 인식
1、Task 를 알다
우선 Task 의 계승 구 조 를 살 펴 보 겠 습 니 다.Task 는 비동기 동작 을 표시 합 니 다.

Task 는 Thread 와 마찬가지 로 System.Threading 네 임 스페이스 에 있 습 니 다.이 는 바로 밀접 한 관 계 를 가 진 다 는 뜻 입 니 다.다음은 저희 가 자세히 보 겠 습 니 다!
2、창설 작업
Task 를 만 드 는 방법 은 두 가지 가 있 는데 하 나 는 직접 만 드 는 것―new 하 나 는 공장 을 통 해 만 드 는 것 이다.다음은 이 두 가지 생 성 방법 을 살 펴 보 겠 습 니 다.

    //       ,     
     var task1 = new Task(() =>
     {
      //TODO you code
     });
이것 은 가장 간단 한 생 성 방법 으로 그 구조 함 수 는 하나의 Action 이 고 그 구조 함 수 는 다음 과 같은 몇 가지 가 있 으 며 비교적 자주 사용 하 는 것 은 앞의 두 가지 이다.

    //       ,    
     var task2 = Task.Factory.StartNew(() =>
     {
      //TODO you code
     });
이 방식 은 정적 공장 을 통 해 Task 를 만 들 고 실행 합 니 다.다음은 콘 솔 프로젝트 를 만 들 겠 습 니 다.코드 는 다음 과 같 습 니 다.
System.Threading.Tasks 이름 컨트롤 인용 을 추가 하려 면

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskDemo
{
  class Program
  {
   static void Main(string[] args)
   {
     var task1 = new Task(() =>
     {
      Console.WriteLine("Hello,task");
     });
     task1.Start();

     var task2 = Task.Factory.StartNew(() =>
     {
      Console.WriteLine("Hello,task started by task factory");
     });

     Console.Read();
   }
  }
}
여기 서 나 는 각각 두 가지 방식 으로 두 개의 task 를 만 들 고 그들 을 실행 시 켰 다.구조 함 수 를 통 해 만 든 task 를 볼 수 있 습 니 다.수 동 Start 가 필요 하고 공장 을 통 해 만 든 Task 가 바로 시 작 됩 니 다.
다음은 Task 의 성명 주 기 를 살 펴 보고 다음 코드 를 작성 합 니 다.

var task1 = new Task(() =>
     {
      Console.WriteLine("Begin");
      System.Threading.Thread.Sleep(2000);
      Console.WriteLine("Finish");
     });
     Console.WriteLine("Before start:" + task1.Status);
     task1.Start();
     Console.WriteLine("After start:" + task1.Status);
     task1.Wait();
     Console.WriteLine("After Finish:" + task1.Status);

     Console.Read();
task 1.Status 는 출력 task 의 현재 상태 입 니 다.출력 결 과 는 다음 과 같 습 니 다.

Start 를 호출 하기 전의 상태 가 Created 인 것 을 볼 수 있 습 니 다.그리고 할당 스 레 드 가 실 행 될 때 까지 기 다 립 니 다.
우리 로부터 Task 의 간략 한 생명 주 기 를 얻 을 수 있다.
Created:기본 초기 화 작업 을 표시 하지만'공장 생 성'인 스 턴 스 는 바로 건 너 뜁 니 다.
WaitingToRun:이 상 태 는 작업 스케줄 러 가 작업 수행 에 스 레 드 를 할당 하 기 를 기다 리 는 것 을 의미 합 니 다.
RanToComplete:퀘 스 트 수행 완료.
 2.Task 의 퀘 스 트 제어
Task 의 가장 매력 적 인 부분 은 바로 그의 임무 통제 입 니 다.task 의 실행 순 서 를 잘 제어 하여 여러 task 를 질서 있 게 할 수 있 습 니 다.다음은 자세히 말씀 드 리 겠 습 니 다.
1、Task.Wait
이전 예 에서,우 리 는 이미 사용 한 적 이 있다.task 1.Wait();작업 이 완료 되 기 를 기다 리 는 것 입 니 다.마지막 task 1 의 상태 가 Complete 로 변 하 는 것 을 볼 수 있 습 니 다.
2、Task.WaitAll
말 그대로 모든 작업 이 완 료 될 때 까지 기다 리 는 것 입 니 다.다음은 코드 를 써 서 보 여 드 리 겠 습 니 다.

static void Main(string[] args)
   {
     var task1 = new Task(() =>
     {
      Console.WriteLine("Task 1 Begin");
      System.Threading.Thread.Sleep(2000);
      Console.WriteLine("Task 1 Finish");
     });
     var task2 = new Task(() =>
     {
      Console.WriteLine("Task 2 Begin");
      System.Threading.Thread.Sleep(3000);
      Console.WriteLine("Task 2 Finish");
     });
     
     task1.Start();
     task2.Start();
     Task.WaitAll(task1, task2);
     Console.WriteLine("All task finished!");

     Console.Read();
   }
그 출력 결 과 는 다음 과 같다.

보 실 수 있 습 니 다.퀘 스 트 1 과 퀘 스 트 2 를 모두 완성 한 후에 야 All task finished 를 출력 합 니 다!
3、Task.WaitAny
이것 은 Task.WaitAll 로 보 내 는 것 입 니 다.모든 작업 이 완료 되 기 를 기다 리 고 계속 아래로 실행 하 는 것 입 니 다.위의 코드 WaitAll 을 WaitAny 로 바 꾸 고 출력 결 과 는 다음 과 같 습 니 다.

4、Task.ContinueWith
바로 첫 번 째 Task 가 완 료 된 후에 다음 Task 를 자동 으로 시작 하여 Task 의 지속 을 실현 하 는 것 입 니 다.다음은 그의 용법 을 살 펴 보고 다음 코드 를 작성 하 겠 습 니 다.

static void Main(string[] args)
   {
     var task1 = new Task(() =>
     {
      Console.WriteLine("Task 1 Begin");
      System.Threading.Thread.Sleep(2000);
      Console.WriteLine("Task 1 Finish");
     });
     var task2 = new Task(() =>
     {
      Console.WriteLine("Task 2 Begin");
      System.Threading.Thread.Sleep(3000);
      Console.WriteLine("Task 2 Finish");
     });

     
     task1.Start();
     task2.Start();
     var result = task1.ContinueWith<string>(task =>
     {
      Console.WriteLine("task1 finished!");
      return "This is task result!";
     });

     Console.WriteLine(result.Result.ToString());


     Console.Read();
   }
실행 결 과 는 다음 과 같 습 니 다.

task 1 이 완 료 된 후에 뒤의 내용 을 실행 하기 시 작 했 고 여기 서 task 의 반환 값 을 얻 었 습 니 다.
Continue With 방법 을 호출 할 때마다 지난번 Task 의 인용 을 입력 하여 지난번 Task 의 상 태 를 검사 할 수 있 습 니 다.예 를 들 어 우 리 는 지난번 Task 의 Result 속성 을 사용 하여 반환 값 을 얻 을 수 있 습 니 다.우 리 는 또 이렇게 쓸 수 있다.

var SendFeedBackTask = Task.Factory.StartNew(() => { Console.WriteLine("Get some Data!"); })
              .ContinueWith<bool>(s => { return true; })
              .ContinueWith<string>(r => 
               {
                 if (r.Result)
                 {
                  return "Finished";
                 }
                 else
                 {
                  return "Error";
                 }
               });
     Console.WriteLine(SendFeedBackTask.Result);
먼저 Get some data 를 출력 한 다음 두 번 째 반환 값 true 를 실행 하고 판단 에 따라 Finished 나 error 를 되 돌려 줍 니 다.출력 결과:
Get some Data!
Finished
사실 위의 문법 은 좀 간소화 하면 이렇게 쓸 수 있다.

Task.Factory.StartNew<string>(() => {return "One";}).ContinueWith(ss => { Console.WriteLine(ss.Result);});
원 출력,이거 알 겠 죠~
 더 많은 ContinueWith 용법 참조:http://technet.microsoft.com/zh-CN/library/dd321405
5、Task 의 취소
앞에서 말 했 듯 이 Task 의 용법 은 다음 과 같 습 니 다.예 를 들 어 우리 가 task 를 시 작 했 거나 이상 이 발생 하거나 사용자 가 취 소 를 클릭 하 는 등 우 리 는 이 임 무 를 취소 할 수 있 습 니 다.
어떻게 Task 를 취소 합 니까?우 리 는 cancellation 의 tokens 를 통 해 Task 를 취소 합 니 다.많은 Task 의 Body 에 순환 이 포함 되 어 있 습 니 다.우 리 는 돌아 가면 서 IsCancellationRequestion 속성 이 True 인지 아 닌 지 를 판단 할 수 있 습 니 다.True 라면 return 또는 이상 을 던 지고 이상 을 던 진 후에 다시 이야기 할 수 있 습 니 다.아직 이상 처 리 된 것 을 말 하지 않 았 기 때 문 입 니 다.
다음은 코드 에서 작업 의 취 소 를 어떻게 실현 하 는 지 보 겠 습 니 다.코드 는 다음 과 같 습 니 다.

var tokenSource = new CancellationTokenSource();
     var token = tokenSource.Token;
     var task = Task.Factory.StartNew(() =>
     {
      for (var i = 0; i < 1000; i++)
      {
        System.Threading.Thread.Sleep(1000);
        if (token.IsCancellationRequested)
        {
         Console.WriteLine("Abort mission success!");
         return;
        }
      }
     }, token);
     token.Register(() =>
     {
      Console.WriteLine("Canceled");
     });
     Console.WriteLine("Press enter to cancel task...");
     Console.ReadKey();
     tokenSource.Cancel();
     Console.ReadKey();//     ,     ,   “Abort mission success!“    
여기 서 Task 를 열 고 token 에 방법 을 등록 하여 정 보 를 출력 한 다음 에 ReadKey 를 실행 하여 사용자 의 입력 을 기다 리 기 시 작 했 습 니 다.사용 자 는 리 턴 을 클릭 한 후에 tokenSource.Cancel 방법 을 실행 하여 작업 을 취소 합 니 다.그 출력 결 과 는 다음 과 같다.

자,오늘 은 여기까지 말씀 드 리 겠 습 니 다.내일 은 task 를 계속 말씀 드 리 겠 습 니 다.다음은 task 의 이상 처리 와 다른 용법 을 말씀 드 려 야 합 니 다.마음 에 드 시 면 저 를 지 켜 보 세 요.업데이트 가 있 으 면 바로 알려 드 리 겠 습 니 다.
 저자:자욱 하 다
 블 로그 주소:http://www.cnblogs.com/yunfeifei/
이상 은 C\#병렬 및 다 중 스 레 드 프로 그래 밍-Task 를 인식 하고 사용 하 는 상세 한 내용 입 니 다.C\#병렬 및 다 중 스 레 드 프로 그래 밍 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기