C # 4.0 Task
에는 System.Threading.Tasks 네임 스페이스가 있습니다. 사이의 진정한 차이는 무엇 Thread
과 Task
. 학습을 위해 샘플 프로그램 (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 스레드 Task
가 Thread
아닌 새로 작성된 항목에서 실행됩니다 .
Task
와 함께 사용하십시오 TaskFactory.StartNew(Action action)
. 여기에서는 대리자를 실행하므로 스레드를 사용하지 않으면 동일한 스레드 (GUI 스레드)에서 실행됩니다. 스레드를 언급 Task
하면 다른 스레드에서 실행할 수 있습니다 . 이것은 대리자를 직접 실행하거나 해당 대리자를 스레드에 연결하고 해당 스레드에서 해당 대리자를 실행할 수있는 불필요한 작업 원인입니다. 사용하지 마십시오. 그냥 불필요합니다. 소프트웨어를 최적화하려는 경우 제거하는 것이 좋습니다.
** Action
는 delegate
입니다.
답변
위의 사항 외에도 다음 사항을 아는 것이 좋습니다.
- 작업은 기본적으로 백그라운드 작업입니다. 포 그라운드 작업을 가질 수 없습니다. 반면 스레드는 배경 또는 전경일 수 있습니다 (동작을 변경하려면 IsBackground 속성을 사용하십시오).
- 스레드 풀에서 생성 된 작업은 스레드를 재활용하여 리소스를 절약합니다. 따라서 대부분의 경우 작업이 기본 선택입니다.
- 작업이 빠르면 스레드 대신 작업을 사용하는 것이 훨씬 좋습니다. 장시간 실행되는 작업의 경우 작업이 스레드보다 많은 이점을 제공하지 않습니다.
답변
나는 보통 Task
Winforms 및 간단한 백그라운드 작업자와 상호 작용하여 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
더 짧은 코드 를 사용할 필요가 없다는 것 입니다.