async / await를 사용하고 있습니다.Task
제비 뽑기 그러나 결코 사용하지 않고 있었던Task.Yield()
모든 설명이 있더라도 솔직히 말해서 나는 왜 내가이 방법을 필요로하는지 이해하지 못한다.
누군가 좋은 예를들 수 있습니까?Yield()
필요한가요?
사용하면async
/await
, 당신이 할 때 당신이 전화하는 방법에 대한 보장은 없습니다await FooAsync()
실제로 비동기 적으로 실행됩니다. 내부 구현은 완전히 동기식 경로를 사용하여 자유롭게 반환 할 수 있습니다.
차단하지 않고 비동기 적으로 일부 코드를 실행하는 API를 만드는 경우 호출 된 메소드가 동기식 (효과적으로 블로킹)으로 실행될 가능성이 있습니다.await Task.Yield()
메소드가 비동기로 강제 실행되고 그 시점에서 제어가 리턴됩니다. 나머지 코드는 현재 상황에서 나중에 실행될 것입니다 (이 시점에서 여전히 동기식으로 실행될 수 있습니다).
이는 "장기 실행"초기화가 필요한 비동기 메서드를 만드는 경우에도 유용합니다 (예 :
private async void button_Click(object sender, EventArgs e)
{
await Task.Yield(); // Make us async right away
var data = ExecuteFooOnUIThread(); // This will run on the UI thread at some point later
await UseDataAsync(data);
}
~없이Task.Yield()
호출 할 때, 메서드는 동 기적으로 첫 번째 호출까지 계속 실행됩니다.await
.
내부적으로,await Task.Yield()
현재 동기화 컨텍스트 또는 임의의 풀 스레드에서 연속을 단순히 대기열에 넣습니다. ifSynchronizationContext.Current
~이다.null
.
그것은효율적으로 구현 된커스텀 웨이터로서. 동일한 효과를 생성하는 덜 효율적인 코드는 다음과 같이 간단 할 수 있습니다.
var tcs = new TaskCompletionSource<bool>();
var sc = SynchronizationContext.Current;
if (sc != null)
sc.Post(_ => tcs.SetResult(true), null);
else
ThreadPool.QueueUserWorkItem(_ => tcs.SetResult(true));
await tcs.Task;
Task.Yield()
이상한 실행 흐름 변경에 대한 바로 가기로 사용할 수 있습니다. 예 :
async Task DoDialogAsync()
{
var dialog = new Form();
Func<Task> showAsync = async () =>
{
await Task.Yield();
dialog.ShowDialog();
}
var dialogTask = showAsync();
await Task.Yield();
// now we're on the dialog's nested message loop started by dialog.ShowDialog
MessageBox.Show("The dialog is visible, click OK to close");
dialog.Close();
await dialogTask;
// we're back to the main message loop
}
즉, 나는 어떤 경우에 대해서도 생각할 수 없다.Task.Yield()
대체 할 수 없다.Task.Factory.StartNew
적절한 작업 스케줄러.
참조 :
Task.Yield()
비동기 메소드의 모의 구현에 사용될 수 있습니다.
await Task.Yield()
메소드를 비동기로 강제 실행하는 이유는 무엇입니까? 비동기 코드? 무거운 동기화 방법을 상상해보십시오. 비동기로 만들려면 다음을 추가하십시오.async
과await Task.Yield()
처음에는 마술처럼 비동기가 될까요? 그것은 거의 모든 동기화 코드를Task.Run()
그리고 가짜 비동기 메서드를 만듭니다. - KrumelurTask.Run
그것을 구현하기 위해,ExecuteFooOnUIThread
UI 스레드가 아니라 스레드 풀에서 실행됩니다. 와await Task.Yield()
, 후속 코드가 현재 컨텍스트에서 실행되는 방식으로 비동기 적으로 강제 실행됩니다 (이후 시점). 일반적으로하는 일이 아니지만 다소 이상한 이유로 필요한 경우 옵션이 있다는 것이 좋습니다. - Reed CopseyExecuteFooOnUIThread()
매우 오래 실행되었지만 오랜 시간 동안 UI 스레드를 차단하여 UI를 응답하지 않게 할 수 있습니다. 맞습니까? - Krumelur