C# 在UWP中,如何显示来自同步函数(即非异步)的messagebox

C# 在UWP中,如何显示来自同步函数(即非异步)的messagebox,c#,uwp,C#,Uwp,有没有一种方法可以包装用于创建对话框的UWP async函数,使它们可以在不使用async关键字的情况下从普通方法调用?例如: var msgbox = new ContentDialog { Title = "Error", Content = "Already at the top of the stack", CloseButtonText = "

有没有一种方法可以包装用于创建对话框的UWP async函数,使它们可以在不使用async关键字的情况下从普通方法调用?例如:

var msgbox = new ContentDialog
             {
                   Title   = "Error",
                   Content = "Already at the top of the stack",
                   CloseButtonText = "OK"
             };
             await msgbox.ShowAsync();
公共任务MsgBox(字符串标题、字符串内容)
{
任务X=null;
var msgbox=新建内容对话框
{
头衔,
内容=内容,
CloseButtonText=“确定”
};
尝试
{
X=msgbox.ShowAsync().AsTask();
返回X;
}
捕获{
返回null;
}
}
私有void B1BtnBack\u单击(对象发送者,路由目标e)
{
MsgBox(“嘟嘟声”,“已经在堆栈顶部”);
返回;
//^^^注意这里。MsgBox返回一个活动任务
//正在运行以显示对话框。这是因为
//下一条语句是直接返回
//返回到UI消息循环。和
//ContentDialog是模态的,意味着它禁用
//在对话框中单击“确定”之前一直显示该页面。
}

不,目前没有办法做到这一点。如果您试图阻止等待对话框关闭,您的应用程序将死锁

我是这样做的(我在UWP刚刚推出时的一些现场演示中看到了这一点):


这在非异步void方法中可以正常工作。

澄清一下:在继续执行之前,是否还需要对话框的结果(如正常的
MessageBox
)?我假设是这样,但请验证。是否可以在非UI线程的ShowAsync()上使用Task.Wait方法?这意味着您从UI线程启动对话框,保存任务变量,并将其传递给工作线程以等待,而不会因为它是工作线程而导致UI死锁?或者您可以在工作线程上使用UI同步上下文来显示异步contentdialog?(可能吗?)另一种可能性。。。将UI线程从工作线程分派到ShowAsync对话框,然后从ShowAsync和工作线程调用Wait()获取任务?可能吗?没有支持的方法来执行此操作。这与WPF/WinForms/Win32之间存在已知的差距。
public Task<ContentDialogResult> MsgBox(string title, string content)
{
    Task<ContentDialogResult> X = null;

    var msgbox = new ContentDialog
    {
        Title = title,
        Content = content,
        CloseButtonText = "OK"
    };

    try
    {
        X = msgbox.ShowAsync().AsTask<ContentDialogResult>();
        return X;
    }
    catch { 
        return null;
    }
}

private void B1BtnBack_Click(object sender, RoutedEventArgs e)
{
    MsgBox("Beep", "Already at the top of stack");
    return; 

    // ^^^ Careful here. MsgBox returns with an active task
    // running to display dialog box.  This works because
    // the next statement is a return that directly 
    // returns to the UI message loop.  And the 
    // ContentDialog is modal meaning it disables 
    // the page until ok is clicked in the dialog box.
}
var msgbox = new ContentDialog
             {
                   Title   = "Error",
                   Content = "Already at the top of the stack",
                   CloseButtonText = "OK"
             };
             var ignored = msgbox.ShowAsync();