首页 文章

隐藏的异步功能

提问于
浏览
0

我正在尝试创建一个只有一个公共函数的库,它返回一个枚举 . 根据我的要求提供支持的私有函数必须是异步的,因为android平台 . 我想要做的是,将唯一的公共函数作为非异步函数使用 . 我知道这可能看起来反直觉,但我有我的理由 . 就函数的使用者而言,他们总是必须在之前将代码作为同步运行,并且这个要求现在不会改变,因为它包含在更高效的库中 . 我不想让他们做等待方法 . 他们不必知道,这就是幕后发生的事情 .

这是我到目前为止所做的,但我正在努力使用公共方法:

public enum DialogResult
{
    Button1 = 1,
    Button2 = 2,
    Button3 = 3,
}

class MsgBox
{
    public  DialogResult Show(String Title, String Caption, Context context)
    {


    }

    private async Task<DialogResult> ShowAsync(String Title, String Caption, Context context)
    {
        return await BuildAsync(Title, Caption, context);
    }

    private Task<DialogResult> BuildAsync(String Title, String Caption,Context context)
    {
        var r = new TaskCompletionSource<DialogResult>();

        new AlertDialog.Builder(context)
        .SetPositiveButton("Yes", (sender, args) =>
        {
            // User pressed yes
            r.SetResult(DialogResult.Button1);
        })
        .SetNegativeButton("No", (sender, args) =>
        {
            // Do nothing
            r.SetResult(DialogResult.Button2);
        })

        .SetMessage(Caption)
        .SetTitle(Title)
        .Show();

        return r.Task;

    }

}

综上所述;我需要这个公共函数,只要从ShowAsync返回后返回我的普通DialogResult,并且不需要使用await调用它自己 .

1 回答

  • 1

    最短和最好的答案是"you can't" . 想想你要做的事情:你的代码需要使用一个API,它需要在完成之前将执行返回到UI线程上的消息循环,但调用代码的代码需要阻止UI线程,直到你的代码完成 . 这是一个逻辑上不可能的设计 .

    但是,您可以使用a couple hacks来强制它起作用 . 一种选择是将工作卸载到另一个线程;但是,它赢得了使用UI线程上运行的需求 . 剩下的hack是运行嵌套的消息循环 .

    运行嵌套消息循环有一个非常严重的问题:重入 . 基本上,一旦你有一个嵌套的消息循环,你的客户的整个应用程序需要处理重入 . 这就是为什么“ DoEvents 是邪恶的” . 这对于推动客户来说是一个巨大的要求,解释和支持要比制定方法更加复杂 async .

相关问题