Tôi cần gọi một async
phương thức trong một catch
khối trước khi ném lại ngoại lệ (với dấu vết ngăn xếp của nó) như sau:
try
{
// Do something
}
catch
{
// <- Clean things here with async methods
throw;
}
Nhưng tiếc là bạn không thể sử dụng await
trong một catch
hoặc finally
khối. Tôi biết được đó là bởi vì trình biên dịch không có bất kỳ cách nào để quay lại catch
khối để thực thi những gì sau await
lệnh của bạn hoặc những thứ tương tự ...
Tôi đã cố gắng sử dụng Task.Wait()
để thay thế await
và tôi đã gặp bế tắc. Tôi đã tìm kiếm trên Web cách tôi có thể tránh điều này và tìm thấy trang web này .
Vì tôi không thể thay đổi các async
phương thức cũng như không biết chúng có sử dụng hay không ConfigureAwait(false)
, tôi đã tạo các phương thức này lấy một phương thức Func<Task>
bắt đầu một phương thức không đồng bộ khi chúng ta đang ở trên một luồng khác (để tránh bế tắc) và chờ hoàn thành:
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());
}
Vì vậy, câu hỏi của tôi là: Bạn có nghĩ rằng mã này là ổn không?
Tất nhiên, nếu bạn có một số cải tiến hoặc biết cách tiếp cận tốt hơn, tôi sẽ lắng nghe! :)
await
trong một khối catch được thực sự cho phép từ C # 6.0 (xem câu trả lời của tôi dưới đây)