다음 코드가 있습니다.
WebClient wc = new WebClient();
string result;
try
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
}
catch
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );
}
기본적으로 URL에서 다운로드하고 싶지만 예외로 실패하면 다른 URL에서 다운로드하고 싶습니다. 물론 두 시간 모두 비동기입니다. 그러나 코드는 컴파일되지 않습니다.
오류 CS1985 : catch 절 본문에서 기다릴 수 없습니다.
좋아, 어떤 이유로 든 금지되어 있지만 여기서 올바른 코드 패턴은 무엇입니까?
편집하다:
좋은 소식은 C # 6.0이 catch 및 finally 블록 모두에서 await 호출을 허용한다는 것 입니다.
답변
업데이트 : C # 6.0은 Await in catch를 지원합니다.
이전 답변 : 플래그를 사용 await
하여 catch
블록 에서 이동하도록 해당 코드를 다시 작성할 수 있습니다 .
WebClient wc = new WebClient();
string result = null;
bool downloadSucceeded;
try
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
downloadSucceeded = true;
}
catch
{
downloadSucceeded = false;
}
if (!downloadSucceeded)
result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );
답변
여기에 표시된대로 Roslyn의 최종 사용자 미리보기 (catch / finally에 Await 아래 나열)에서 catch 블록에서 대기하는 것이 가능하며 C # 6에 포함됩니다.
나열된 예는 다음과 같습니다.
try … catch { await … } finally { await … }
업데이트 : 최신 링크가 추가되었으며 C # 6에있을 것입니다.
답변
이것은 작동하는 것 같습니다.
WebClient wc = new WebClient();
string result;
Task<string> downloadTask = wc.DownloadStringTaskAsync(new Uri("http://badurl"));
downloadTask = downloadTask.ContinueWith(
t => {
return wc.DownloadStringTaskAsync(new Uri("http://google.com/")).Result;
}, TaskContinuationOptions.OnlyOnFaulted);
result = await downloadTask;
답변
이것을 시도하십시오 :
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
( Wait()
엔딩 참조 )
답변
C # 6.0을 사용합니다. 이 링크보기
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
답변
폴백 작업을 기다린 후 예외를 다시 발생시키는 데 사용하는 패턴 :
ExceptionDispatchInfo capturedException = null;
try
{
await SomeWork();
}
catch (Exception e)
{
capturedException = ExceptionDispatchInfo.Capture(e);
}
if (capturedException != null)
{
await FallbackWork();
capturedException.Throw();
}
답변
다음과 같이 람다 식을 사용할 수 있습니다.
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}