private void RunAsync()
{
string param = "Hi";
Task.Run(() => MethodWithParameter(param));
}
private void MethodWithParameter(string param)
{
}
편집하다
대중적인 요구로 인해 Task
시작된 것이 호출 스레드와 병렬로 실행 된다는 점에 유의해야합니다 . 기본값이라고 가정하면 TaskScheduler
.NET ThreadPool
. 어쨌든 이것은 전달되는 매개 변수 Task
가 잠재적으로 한 번에 여러 스레드에 의해 액세스되어 공유 상태 가되도록 고려해야 함을 의미합니다 . 여기에는 호출 스레드에서 액세스하는 것이 포함됩니다.
위의 코드에서 그 경우는 완전히 논쟁의 여지가 있습니다. 문자열은 변경할 수 없습니다. 그래서 나는 그것들을 예로 사용했습니다. 그러나 당신이 사용하지 않는다고 String
...
한 가지 해결책은 async
및 await
. 이것은 기본적으로 SynchronizationContext
호출 스레드의 를 캡처하고 호출 후 나머지 메서드에 대한 연속을 await
생성하고 생성 된 Task
. 이 메서드가 WinForms GUI 스레드에서 실행되는 경우 유형은 WindowsFormsSynchronizationContext
.
연속 작업은 캡처 된 항목에 다시 게시 된 후 실행 SynchronizationContext
됩니다. 기본적으로 만 다시 실행됩니다. 따라서 await
통화 후 시작한 스레드로 돌아갑니다 . 특히를 사용하여 다양한 방법으로이를 변경할 수 있습니다 ConfigureAwait
. 즉, 그 방법의 나머지 부분까지 계속되지 않습니다 후 가 Task
다른 스레드에 완료했습니다. 그러나 호출 스레드는 나머지 메서드가 아닌 병렬로 계속 실행됩니다.
나머지 메소드 실행을 완료하기 위해 기다리는 것은 바람직 할 수도 있고 그렇지 않을 수도 있습니다. 나중에 해당 메서드에서에 전달 된 매개 변수에 액세스하는 것이 없으면 전혀 Task
사용하지 않을 수 있습니다 await
.
또는 나중에 메서드에서 이러한 매개 변수를 사용할 수도 있습니다. await
안전하게 작업을 계속할 수 있으므로 즉시 할 이유가 없습니다 . Task
반환 된 값을 변수에 저장할 수 await
있고 나중에 같은 방법으로도 저장할 수 있습니다 . 예를 들어, 다른 작업을 한 후 전달 된 매개 변수에 안전하게 액세스해야하는 경우입니다. 다시 말하지만, 당신은 할 수 없습니다 필요 await
온 Task
당신이 그것을 실행하면 바로.
어쨌든 전달 된 매개 변수와 관련하여이 스레드를 안전하게 만드는 간단한 방법 Task.Run
은 다음과 같이하는 것입니다.
먼저 장식한다 RunAsync
과 async
:
private async void RunAsync()
중요 사항
링크 된 문서에서 언급했듯이 표시된 메서드는 void를 반환 하지 않는 것이 좋습니다 . 이에 대한 일반적인 예외는 버튼 클릭 등과 같은 이벤트 핸들러입니다. 그들은 무효를 반환해야합니다. 그렇지 않으면 항상 또는을 사용할 때 반환하려고합니다 . 몇 가지 이유로 좋은 습관입니다.async
Task
Task<TResult>
async
이제 아래와 같이 await
실행할 수 Task
있습니다. await
없이는 사용할 수 없습니다 async
.
await Task.Run(() => MethodWithParameter(param));
따라서 일반적으로 await
작업을 수행하면 매개 변수에 전달 된 매개 변수를 한 번에 여러 스레드에서 수정하는 모든 함정과 함께 잠재적 인 공유 리소스로 취급하는 것을 피할 수 있습니다. 또한 폐쇄에 주의하십시오 . 나는 그것들을 깊이 다루지 않을 것이지만 링크 된 기사는 그것에 대해 훌륭한 일을한다.
사이드 노트
약간의 주제이지만 WinForms GUI 스레드에서으로 표시되어 있으므로 모든 유형의 "차단"을 사용하려면주의해야합니다 [STAThread]
. 사용 await
하면 전혀 차단되지 않지만 일종의 차단과 함께 사용되는 경우가 있습니다.
기술적으로 WinForms GUI 스레드를 차단할 수 없기 때문에 "Block"은 따옴표로 묶 입니다. 예, 당신이 사용하는 경우 lock
윈폼 GUI에이 스레드 합니다 아직도의 "차단"생각 당신에도 불구하고, 메시지를 펌프. 그렇지 않습니다.
이것은 매우 드문 경우에 기괴한 문제를 일으킬 수 있습니다. lock
예를 들어 그림을 그릴 때 를 사용하고 싶지 않은 이유 중 하나입니다 . 그러나 그것은 변덕스럽고 복잡한 경우입니다. 그러나 나는 그것이 미친 문제를 일으키는 것을 보았다. 그래서 완전성을 위해 기록했습니다.