【问题标题】:Hidden async function隐藏的异步功能
【发布时间】:2014-10-28 13:35:02
【问题描述】:

我正在尝试创建一个库,它只有一个公共函数,它返回一个枚举。由于 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 调用它自己。

【问题讨论】:

  • 喜欢ShowAsync(...).Result?
  • 感谢 DavidG,但我试过了,它使 UI 死锁。
  • ConfigureAwait 怎么样?
  • 它需要是异步的。这只是使用这样的 UI 的本质所固有的。您将无法使该方法同步;任何这样做的尝试都只会阻塞 UI 线程。
  • 不要做“同步异步”。选择,要么一直异步,要么一直同步。如果您的消费者必须是同步的,请不要使用异步。

标签: c# android asynchronous xamarin async-await


【解决方案1】:

最短和最好的答案是“你不能”。想一想您正在尝试做什么:您的代码需要使用一个 API,该 API 需要 在 UI 线程上将执行返回到消息循环,然后才能完成,但调用您的代码的代码需要 em>阻塞 UI 线程,直到你的代码完成。这是一个逻辑上不可能的设计。

但是,您可以使用a couple hacks 来尝试强制它工作。一种选择是将工作卸载到另一个线程;但是,这不适用于您的情况,因为您使用的 API 需要在 UI 线程上运行。剩下的技巧是运行一个嵌套的消息循环。

运行嵌套消息循环有一个非常严重的问题:重入。本质上,一旦你有了一个嵌套的消息循环,你的客户的整个应用程序就需要处理重入。这就是为什么“DoEvents 是邪恶的”的原因。这是推动您的客户的一项巨大要求,解释和支持比仅仅制作方法async 要复杂得多。

【讨论】:

  • 感谢您的详细回答,并尝试破解解决方案。同意,最好避免黑客攻击。我想我将不得不接受失败,就像我之前的许多人一样。
猜你喜欢
  • 2010-09-17
  • 2010-09-13
  • 2010-09-23
  • 2020-06-01
  • 2011-07-21
  • 1970-01-01
  • 2012-09-23
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多