ฉันต้องเรียกใช้async
เมธอดในcatch
บล็อกก่อนที่จะโยนข้อยกเว้นอีกครั้ง (ด้วยการติดตามสแต็ก) เช่นนี้
try
{
// Do something
}
catch
{
// <- Clean things here with async methods
throw;
}
แต่น่าเสียดายที่คุณไม่สามารถใช้await
ใน a catch
หรือfinally
block ได้ ฉันได้เรียนรู้ว่าเป็นเพราะคอมไพเลอร์ไม่มีทางย้อนกลับไปในcatch
บล็อกเพื่อดำเนินการตามawait
คำสั่งของคุณหรืออะไรทำนองนั้น ...
ฉันพยายามใช้Task.Wait()
เพื่อแทนที่await
และฉันมีการหยุดชะงัก ฉันค้นหาบนเว็บว่าฉันจะหลีกเลี่ยงปัญหานี้ได้อย่างไรและพบไซต์นี้
เนื่องจากฉันไม่สามารถเปลี่ยนasync
วิธีการและฉันไม่รู้ว่าพวกเขาใช้ConfigureAwait(false)
หรือไม่ฉันจึงสร้างวิธีการเหล่านี้ขึ้นมาซึ่งใช้วิธีFunc<Task>
เริ่มต้นวิธี async เมื่อเราอยู่ในเธรดอื่น (เพื่อหลีกเลี่ยงการหยุดชะงัก) และรอให้มันเสร็จสิ้น:
public static void AwaitTaskSync(Func<Task> action)
{
Task.Run(async () => await action().ConfigureAwait(false)).Wait();
}
public static TResult AwaitTaskSync<TResult>(Func<Task<TResult>> action)
{
return Task.Run(async () => await action().ConfigureAwait(false)).Result;
}
public static void AwaitSync(Func<IAsyncAction> action)
{
AwaitTaskSync(() => action().AsTask());
}
public static TResult AwaitSync<TResult>(Func<IAsyncOperation<TResult>> action)
{
return AwaitTaskSync(() => action().AsTask());
}
คำถามของฉันคือคุณคิดว่ารหัสนี้ใช้ได้หรือไม่?
แน่นอนถ้าคุณมีการปรับปรุงบางอย่างหรือรู้แนวทางที่ดีกว่าฉันรับฟัง! :)
await
ใน catch block ได้ตั้งแต่ C # 6.0 (ดูคำตอบของฉันด้านล่าง)