c# - A good solution for await in try/catch/finally? -
i need call async method in catch block before throwing again exception (with stack trace) :
try { // } catch { // <- clean things here async methods throw; } but unfortunately can't use await in catch or finally block. learned it's because compiler doesn't have way go in catch block execute after await instruction or that...
i tried use task.wait() replace await , got deadlock. searched on web how avoid , found this site.
since can't change async methods nor know if use configureawait(false), created these methods take func<task> starts async method once on different thread (to avoid deadlock) , waits completion:
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()); } so questions is: think code okay?
of course, if have enhancements or know better approach, i'm listening! :)
you can move logic outside of catch block , rethrow exception after, if needed, using exceptiondispatchinfo.
static async task f() { exceptiondispatchinfo capturedexception = null; try { await taskthatfails(); } catch (myexception ex) { capturedexception = exceptiondispatchinfo.capture(ex); } if (capturedexception != null) { await exceptionhandler(); capturedexception.throw(); } } this way, when caller inspects exception's stacktrace property, still records inside taskthatfails thrown.
Comments
Post a Comment