여기 몇 가지 혼란스러워하는 것 같습니다. 당신은 무엇을 요구하는지 것은 이미 사용 가능한 System.Threading.Tasks1, async및 awaitC # 5 단지 같은 기능에 대한 좀 더 좋은 문법 설탕을 제공 할 것입니다.
Winforms 예제를 사용해 봅시다. 폼에 버튼과 텍스트 상자를 놓고이 코드를 사용하십시오 :
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew<int>(() => DelayedAdd(5, 10))
.ContinueWith(t => DelayedAdd(t.Result, 20))
.ContinueWith(t => DelayedAdd(t.Result, 30))
.ContinueWith(t => DelayedAdd(t.Result, 50))
.ContinueWith(t => textBox1.Text = t.Result.ToString(),
TaskScheduler.FromCurrentSynchronizationContext());
}
private int DelayedAdd(int a, int b)
{
Thread.Sleep(500);
return a + b;
}
그것을 실행하고 당신은의 (a)는 UI 스레드와 (b) 당신이 오류 일반적인 "유효하지 크로스 스레드 작업을"하지 않습니다 차단하지 않습니다 볼 수 있습니다 - 당신은 제거하지 않는 TaskScheduler마지막에서 인수 ContinueWith에를 어떤 경우에
이것은 bog 표준 연속 전달 스타일 입니다. 마술은 TaskScheduler클래스에서, 구체적으로에 의해 검색된 인스턴스 에서 발생 합니다 FromCurrentSynchronizationContext. 이것을 연속으로 전달하면 FromCurrentSynchronizationContext메소드 라고하는 스레드 ( 이 경우 UI 스레드) 에서 연속을 실행해야한다고 알립니다 .
웨이터는 시작한 스레드와 연속이 필요한 스레드를 알고 있다는 점에서 약간 더 정교합니다. 따라서 위의 코드는 좀 더 자연스럽게 작성 될 수 있습니다 .
private async void button1_Click(object sender, EventArgs e)
{
int a = await DelayedAddAsync(5, 10);
int b = await DelayedAddAsync(a, 20);
int c = await DelayedAddAsync(b, 30);
int d = await DelayedAddAsync(c, 50);
textBox1.Text = d.ToString();
}
private async Task<int> DelayedAddAsync(int a, int b)
{
Thread.Sleep(500);
return a + b;
}
이 두 가지는 매우 비슷해 보이며 실제로 는 매우 비슷합니다. 이 DelayedAddAsync메소드는 이제 Task<int>대신을 반환 int하므로 await계속 각 연속으로 연속을 두드리는 것입니다. 가장 큰 차이점은 각 줄에서 동기화 컨텍스트를 전달한다는 것이므로 마지막 예에서와 같이 명시 적으로 수행 할 필요가 없습니다.
이론적으로는 차이점이 훨씬 더 중요합니다. 두 번째 예에서 button1_Click메서드의 모든 단일 행 은 실제로 UI 스레드에서 실행되지만 작업 자체 ( DelayedAddAsync)는 백그라운드에서 실행됩니다. 첫 번째 예에서는 모든 것을 실행은에 배경 , 제외시켰다 에 할당을 위해 textBox1.Text우리가 명시 적으로 UI 스레드의 동기화 컨텍스트에 첨부했습니다있다.
정말 흥미로운 await점은 대기자가 차단 호출없이 동일한 방법 으로 들어오고 나올 수 있다는 사실입니다 . 을 호출 await하면 현재 스레드가 메시지 처리로 돌아갑니다. 완료되면 대기자는 중단 된 것과 동일한 스레드에서 중단 된 위치를 정확하게 선택합니다.하지만 질문 의 Invoke/ BeginInvoke대비 측면 에서 나는 ' 오래 전에 그 일을 그만 두어야한다고 말해서 죄송합니다.
await기능에 관한 한, 가능성은 거의 없습니다 . 그것은 계속해서 지나가는 많은 구문 설탕입니다 . 아마도 WinForms에 도움이 될 다른 관련없는 개선이 있습니까? 그것은 C #이 아닌 .NET 프레임 워크 자체에 속합니다.