비동기식 C# 기능을 사용하면 비동기식 흐름을 동기식 흐름과 같은 것으로 다시 작성할 수 있습니다. 당신은 내가 당신의 코드와 유사한 몇 가지 코드 생성 한 완전한 예를 제공하기 위해 코드의 일부 조각을 제공하고 있습니다 : 이벤트를 발사하기 전에
class StartEventArgs : EventArgs {
public StartEventArgs(Int32 sessionId, Int32 errorCode) {
SessionId = sessionId;
ErrorCode = errorCode;
}
public Int32 SessionId { get; private set; }
public Int32 ErrorCode { get; private set; }
}
delegate void StartEventHandler(Object sender, StartEventArgs e);
class ServiceProvider {
public event StartEventHandler Start;
public void Startup(Boolean succeed) {
Thread.Sleep(TimeSpan.FromSeconds(1));
if (succeed)
OnStart(new StartEventArgs(321, 0));
else
OnStart(new StartEventArgs(0, 123));
}
protected void OnStart(StartEventArgs e) {
var handler = Start;
if (handler != null)
handler(this, e);
}
}
가 ServiceProvider.Startup
방법은 초 동안 지연됩니다 그 중 신호 성공 또는 실패 제공된 succeed
매개 변수에 따라 이 방법은 다소 바보 스럽지만 잘하면 사용자의 ServiceProvider.Startup
메소드의 동작과 유사합니다.
당신은 TaskCompletionSource
사용하여 작업에 비동기 시작을 변환 할 수 있습니다 : 생산 코드합니다 (Start
이벤트로부터 신호 오류가 Exception
로 변환하는 방법을
Task<Int32> PerformStartup(ServiceProvider serviceProvider, Boolean succeed) {
var taskCompletionSource = new TaskCompletionSource<Int32>();
serviceProvider.Start += (sender, e) => {
if (e.ErrorCode > 0)
throw new Exception(e.ErrorCode.ToString());
taskCompletionSource.SetResult(e.SessionId);
};
serviceProvider.Startup(succeed);
return taskCompletionSource.Task;
}
공지 사항을 대신 입력 한 사용자 지정 예외를 사용해야합니다).
비동기를 사용하여 매우 많은 동기 코드와 같은 실제로 비동기 비록 당신이 지금 보이는 코드를 작성할 수 있습니다 C 번호의 기능을 기다리고 있습니다 : 오류가 Start
이벤트에 의해보고
async void Startup(Boolean succeed) {
var serviceProvider = new ServiceProvider();
try {
var sessionId = await PerformStartup(serviceProvider, succeed);
Console.WriteLine(sessionId);
}
catch (Exception ex) {
Console.WriteLine(ex);
}
}
경우 당신이 지금 할 수있는 catch
블록에서 처리하십시오. 또한 세션 ID는 단순히 함수의 반환 값입니다. "마법"은 Task
에 await
을 사용하면 작업 완료시 작업 결과를 반환하고 작업에 예외가 발생하면 작업을 기다리는 스레드에서 잡힐 수 있다는 것입니다.