[C#] 작업과 스레드의 차이점은 무엇입니까?

C # 4.0 Task에는 System.Threading.Tasks 네임 스페이스가 있습니다. 사이의 진정한 차이는 무엇 ThreadTask. 학습을 위해 샘플 프로그램 (MSDN에서 가져온 도움)을 사용했습니다.

Parallel.Invoke
Parallel.For
Parallel.ForEach 

아이디어가 명확하지 않기 때문에 많은 의심이 있습니다.

나는 처음에 비슷한 유형의 질문에 대해 Stackoverflow를 검색했지만이 질문 제목으로 동일하지 않을 수 있습니다. 누구든지 여기에 게시 된 동일한 유형의 질문에 대해 알고 있다면 친절하게 링크를 참조하십시오.



답변

작업은 당신이 원하는 것입니다.

스레드는 해당 작업을 수행 할 수있는 많은 작업자 중 하나입니다.

.NET 4.0 용어에서 작업 은 비동기 작업을 나타냅니다. 스레드는 작업을 청크로 분할하고 별도의 스레드에 할당하여 해당 작업을 완료하는 데 사용됩니다.


답변

컴퓨터 과학 용어로, a Task미래 또는 약속 입니다. (어떤 사람들은이 두 단어를 동의어로 사용하고, 어떤 사람들은 다르게 사용하며, 아무도 정확한 정의 에 동의 할 수 없습니다 .) 기본적으로, Task<T>당신을 돌려 주는 “약속” T, 그러나 지금은 아니고 여보, 좀 바빠요. 나중에 다시 오세요?

A Thread는 그 약속을 이행하는 방법입니다. 그러나 모든 사람 Task에게 새로운 브랜드가 필요한 것은 아닙니다 Thread. (실제로 스레드를 작성하는 것은 스레드 풀에서 기존 스레드를 재사용하는 것보다 훨씬 비싸기 때문에 종종 바람직하지 않습니다. 잠시 후에 더 많은 값을 얻으십시오.) 대기중인 값이 파일 시스템 또는 다른 요청을 처리 할 수있을 때 스레드가 앉아서 데이터를 기다릴 필요가 없습니다. 대신, Task준비가되면 값을 받기 위해 콜백을 등록 할 수 있습니다.

특히,는 Task않습니다 하지이유는 그것이 값을 반환하는 등 시간이 오래 걸리는 것입니다. 이 는 계산하는 데 시간이 오래 걸린다, 또는 그것이 가져 오는 데 시간이 오래 걸린다 수 있습니다. 전자의 경우에만 a Thread를 사용하여 a 를 실행합니다 Task. .NET에서는 스레드가 엄청나게 비싸므로 일반적으로 가능한 많은 스레드를 피하고 여러 CPU에서 여러 개의 무거운 계산을 실행하려는 경우에만 실제로 사용합니다. 예를 들어 Windows의 경우 스레드의 무게는 12 KiByte ( 리눅스에서는 스레드의 무게가 4KB, Erlang / BEAM, 심지어 400 바이트에 불과합니다. .NET에서는 1MiByte입니다!)


답변

베어 메탈은 아마도 그것을 사용할 필요가 없습니다. 아마도 작업을 사용하고 LongRunning.NET Framework 4 (2002 년 2 월) 이상 (.NET)에 포함 된 TPL-Task Parallel Library의 이점을 활용할 수 있습니다. 핵심).

작업

스레드 위의 추상화. 이 스레드 풀을 사용 (당신이로 작업을 지정하지 않는 LongRunning때문에, 새로운 스레드가 당신을 위해 후드 아래에 생성 된 경우, 작업을).

스레드 풀

이름에서 알 수 있듯이 스레드 풀. .NET 프레임 워크가 제한된 수의 스레드를 처리하고 있습니까? 왜? 코어 수가 8 개인 프로세서에서 비싼 CPU 작업을 실행하기 위해 100 개의 스레드를 여는 것은 좋은 생각이 아닙니다. 프레임 워크는 스레드를 재사용하고 (각 작업마다 스레드를 작성 / 종료하지 않음) CPU를 태우지 않는 방식으로 스레드를 재사용하여이 풀을 유지 관리합니다.

좋아,하지만 언제 사용합니까?

다시 시작 : 항상 작업을 사용하십시오.

작업은 추상화이므로 사용하기가 훨씬 쉽습니다. 나는 항상 작업을 사용하려고 시도하고 문제가 발생하여 직접 스레드를 처리 해야하는 경우 (아마도 1 %) 스레드를 사용하는 것이 좋습니다.

그러나 다음 사항에 유의하십시오.

  • I / O 바운드 : I / O 바운드 작업 (데이터베이스 호출, 읽기 / 쓰기 파일, API 호출 등)의 경우 일반 작업 사용을 피하고 LongRunning작업 ( 필요한 경우 스레드 )을 사용하십시오. 작업을 사용하면 몇 개의 스레드가 사용 중이고 차례를 풀을 기다리는 다른 작업이 많은 스레드 풀이 생길 수 있습니다.
  • CPU 바운드 : CPU 바운드 작업의 경우 내부 작업이 스레드 풀을 사용하는 일반적인 작업 만 사용하면됩니다.

답변

당신이 사용할 수있는 Task그 첨부 당신이해야 할 작업을 지정 Task로모그래퍼 Thread. 따라서 GUI 스레드 TaskThread아닌 새로 작성된 항목에서 실행됩니다 .

Task와 함께 사용하십시오 TaskFactory.StartNew(Action action). 여기에서는 대리자를 실행하므로 스레드를 사용하지 않으면 동일한 스레드 (GUI 스레드)에서 실행됩니다. 스레드를 언급 Task하면 다른 스레드에서 실행할 수 있습니다 . 이것은 대리자를 직접 실행하거나 해당 대리자를 스레드에 연결하고 해당 스레드에서 해당 대리자를 실행할 수있는 불필요한 작업 원인입니다. 사용하지 마십시오. 그냥 불필요합니다. 소프트웨어를 최적화하려는 경우 제거하는 것이 좋습니다.

** Actiondelegate입니다.


답변

위의 사항 외에도 다음 사항을 아는 것이 좋습니다.

  1. 작업은 기본적으로 백그라운드 작업입니다. 포 그라운드 작업을 가질 수 없습니다. 반면 스레드는 배경 또는 전경일 수 있습니다 (동작을 변경하려면 IsBackground 속성을 사용하십시오).
  2. 스레드 풀에서 생성 된 작업은 스레드를 재활용하여 리소스를 절약합니다. 따라서 대부분의 경우 작업이 기본 선택입니다.
  3. 작업이 빠르면 스레드 대신 작업을 사용하는 것이 훨씬 좋습니다. 장시간 실행되는 작업의 경우 작업이 스레드보다 많은 이점을 제공하지 않습니다.

답변

나는 보통 TaskWinforms 및 간단한 백그라운드 작업자와 상호 작용하여 UI를 멈추지 않도록합니다. 여기에 내가 선호하는 예가 있습니다.Task

private async void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    await Task.Run(() => {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
    })
    buttonDownload.Enabled = true;
}

VS

private void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    Thread t = new Thread(() =>
    {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
        this.Invoke((MethodInvoker)delegate()
        {
            buttonDownload.Enabled = true;
        });
    });
    t.IsBackground = true;
    t.Start();
}

차이점은 MethodInvoker더 짧은 코드 를 사용할 필요가 없다는 것 입니다.


답변

작업은 수행하려는 작업과 같으며 Thread는 여러 프로세스 노드를 통해 이러한 작업을 관리하는 데 도움이됩니다. 작업은 스레딩과 같은 경량 옵션은 복잡한 코드 관리로 이어질 수 있습니다
내가 (세계 제일)는 항상 MSDN에서 읽을 제안합니다

작업