问题
I had a need to call ShowDialog
on a Window
, but had to do so in a non-blocking way. This is the solution I came up with.
I'm wondering if this violates any principles around Async
/Await
or if there is anything that I'm not seeing with this design.
public static class WindowExtensions {
private delegate bool? ShowDialogAsyncDelegate();
public static async Task<bool?> ShowDialogAsync(this Window window) {
var asyncDelegate = new ShowDialogAsyncDelegate(window.ShowDialog);
var dispatcherOperation = window.Dispatcher.BeginInvoke(asyncDelegate);
await dispatcherOperation.Task.ConfigureAwait(false); // <-- In this usage, is this safe to always be 'False'?
return (bool?)dispatcherOperation.Result;
}
}
I'm planning on using it like this...
// If I want the caller awaiting on this to be in a try-catch, is it safe to be 'async void' here?
async void DoSomething(){
var someDialogWindow = new SomeDialogWindow();
var showDialogAsyncTask = someDialogWindow.ShowDialogAsync().ConfigureAwait(false); // <-- In this usage, this depends on what I do after `await showDialogAsyncTask`, correct?
// Immediately do this code after showing the window even though it's shown modally...
Bla();
Bla();
Bla();
// Now await on the result (possibly on a new sync context bc of the .ConfigureAwait(false) above
bool? dialogResult = await showDialogAsyncTask;
doSomethingWithResult(dialogResult);
}
In the above, if you needed to interact with the window itself after the await
call, or need to be back on the main thread, you would not use .ConfigureAwait(false)
but here I'm only interested in the result and it can run on any thread, hence my adding it.
Also, the inner .ConfigureAwait(false)
in the extension method, since there's nothing in there that uses anything from that synchronization context, that can always be False
, correct?
So is this considered a 'safe' practice, or am I opening myself up to something I'm not yet seeing?
Update
Digging around more, I found something similar that uses Task.Yield
and it appears to do the same thing, albeit much more simply. Is this identical to the above functionality-wise?
public static async Task<bool?> ShowDialogAsync(this Window window, bool configureAwait = true) {
await Task.Yield();
return window.ShowDialog();
}
来源:https://stackoverflow.com/questions/65453171/is-this-the-proper-safe-way-to-create-a-showdialogasync-extension-method-on-win