여기 몇 가지 혼란스러워하는 것 같습니다. 당신은 무엇을 요구하는지 것은 이미 사용 가능한 System.Threading.Tasks
1, async
및 await
C # 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 프레임 워크 자체에 속합니다.