답변:
가장 좋은 방법은 기능이 async void불인 경우에만 기능을 표시 하고 방법을 잊어 버리고 기다리는 경우에는로 표시해야합니다 async Task.
만약 당신이 여전히 기다리고 싶다면, 그렇게 포장하십시오 await Task.Run(() => blah())
await Task.Run(() => An_async_void_method_I_can_not_modify_now())
await Task.Run(() => blah())오해의 소지가 있습니다. 이것은 async function의 완료를 기다리지 blah않고 작업의 (사소한) 생성을 기다리며 blah()완료 직전에 계속 됩니다.
Thread.Sleep비동기식은 아닙니다. 이 질문은 async void기능 대기에 관한 것입니다.async void blah() { Task.Delay(10000); }
AutoResetEvent를 수행하고 함수를 호출 한 다음 AutoResetEvent를 기다린 다음 완료되었음을 알면 async void 안에 설정하십시오.
당신은 또한 당신의 공허 비동기에서 반환 작업을 기다릴 수 있습니다
실제로 수동으로 아무것도 할 필요가 없으며 await키워드 blah()는 반환 될 때까지 함수 실행을 일시 중지 합니다.
private async void SomeFunction()
{
var x = await LoadBlahBlah(); <- Function is not paused
//rest of the code get's executed even if LoadBlahBlah() is still executing
}
private async Task<T> LoadBlahBlah()
{
await DoStuff(); <- function is paused
await DoMoreStuff();
}
T객체 blah()반환 유형
당신은 정말 할 수 기능은 그렇게 할 수 없다awaitvoidLoadBlahBlah()void
LoadBlahBlah(),하지 마칩니다blah()
나는 이것이 오래된 질문이라는 것을 알고 있지만 이것은 여전히 겪고있는 문제이지만 여전히 비동기 무효 서명 방법에서 async / await를 사용할 때이를 올바르게 수행하는 명확한 해결책은 없습니다.
그러나 void 메서드 내에서 .Wait ()이 제대로 작동한다는 것을 알았습니다.
async void와 void는 동일한 서명을 가지므로 다음을 수행해야 할 수도 있습니다.
void LoadBlahBlah()
{
blah().Wait(); //this blocks
}
혼란스럽게도 충분한 비동기 / 대기는 다음 코드에서 차단되지 않습니다.
async void LoadBlahBlah()
{
await blah(); //this does not block
}
코드를 디 컴파일 할 때 async void는 내부 작업 (비동기 작업과 동일)을 생성하지만 서명은 내부 작업을 반환하도록 지원하지 않기 때문에
이것은 내부적으로 비동기 void 메소드가 내부적으로 비동기 메소드를 "대기"할 수 있음을 의미합니다. 내부 작업이 언제 완료되는지 외부에서 알 수 없습니다.
따라서 제 결론은 비동기 void가 의도 한대로 작동하고 내부 작업의 피드백이 필요한 경우 대신 비동기 작업 서명을 사용해야한다는 것입니다.
잘만되면 나의 학대는 답을 찾는 사람에게도 의미가있다.
편집 : 나는 예제 코드를 만들고 실제로 무슨 일이 일어나고 있는지 확인하기 위해 디 컴파일했다.
static async void Test()
{
await Task.Delay(5000);
}
static async Task TestAsync()
{
await Task.Delay(5000);
}
로 바뀝니다 (편집 : 본문 코드는 여기가 아니라 상태 머신에 있지만 상태 머신은 기본적으로 동일하므로 추가하지 않아도됩니다)
private static void Test()
{
<Test>d__1 stateMachine = new <Test>d__1();
stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
}
private static Task TestAsync()
{
<TestAsync>d__2 stateMachine = new <TestAsync>d__2();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
AsyncVoidMethodBuilder 또는 AsyncTaskMethodBuilder는 실제로 Start 메서드에 차단할 힌트를주는 코드가 없으며 시작된 후에는 항상 비동기 적으로 실행됩니다.
반환 작업이 없으면 의미가 완료되었는지 확인할 방법이 없습니다.
예상대로 비동기 실행 작업 만 시작한 다음 코드에서 계속됩니다. 비동기 작업은 먼저 작업을 시작한 다음 반환합니다.
그래서 내 대답은 비동기 void를 절대 사용하지 않는 것 같습니다. 작업이 언제 완료되는지 알아야 할 경우 비동기 작업의 목적입니다.