c# - 异步/等待 Android 下的不良做法?

标签 c# android xamarin.android xamarin async-await

目前我正在将现有的 C# Windows 8/iOS 应用程序移植到 Android(使用 Xamarin)。

我在文件 IO、对话框、网络等方面使用了很多 async/await……

当应用程序在 await 调用期间暂停/挂起时会发生什么? 在 Windows 和 iOS 下有两种可能:

  • 应用稍后恢复,就好像什么都没发生过一样
  • 如果内存不足,应用程序将终止。

在这两种情况下,都没有内存泄漏,控制流也没有变化。

但是,在 Android 下,可以在进程保持 Activity 状态时销毁并重新创建 Activity。在我对异步/等待的理解中,这意味着:

  • 未关闭的对话框将永远等待,这意味着可从调用者访问的对象(“t​​his”、局部变量等)将永远保留在内存中(内存泄漏)
  • 当等待的网络请求完成而前一个 Activity 已被 Android 销毁时,“等待”之后的代码(例如文件写入)可能会发生冲突,因为存在两个正在运行的 Activity 实例。

我的假设是真的吗?如果是,可以做什么? (没有让程序像发明async/await之前那么复杂)

最佳答案

Android Activity 保证在 Activity 被停用/销毁之前调用 OnPause 并在它启动时调用 OnResume(参见 http://developer.android.com/training/basics/activity-lifecycle/index.html)。

如果您的 Activity 中有可用的 CancellationTokenSource 会怎么样。然后在 OnPause 中你可以调用 Cancel 然后使用:

try
{
    // Your async code
    ...
}
catch (OperationCancelledException e)
{
}

另见 http://msdn.microsoft.com/en-us/library/jj155759.aspx用于取消异步任务。

更多的是建议而不是明确的答案,但我希望它能有所帮助。

编辑:

当我开始在我的代码中引入 async/await 时,我发现它就像一个僵尸病毒。一旦你开始异步,你会发现它遍布你代码的其余部分。可能是出于同样的原因,您收到了很多异步调用。通常有两个规则要遵循:

  1. 将方法声明为 public async Task Foo() 而不是 public async void Foo()
  2. Don't block on async code

在我自己的实践中,我发现了 2 个可以打破这些一般规则的地方。

  1. 如果您位于代码的“顶部”(即 UI),可能在某些地方您必须将代码声明为 async void,因为您要覆盖的委托(delegate)将 void 作为返回类型。一个典型的例子是使用 button.Click 方法。
  2. 我有一个数据库调用,它在数据库中查找单个值。如果我将其转换为异步,很多 我在别处的代码将不得不更改。我发现如果你保证,我的意思是保证,在你的代码的“底部”,特别是你调用的方法下面的方法都没有使用异步,那么你可以安全地在任务上调用 .Result。这使我免于不必要地异步处理一半代码。

希望这对您有所帮助。

关于c# - 异步/等待 Android 下的不良做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22612775/

相关文章:

c# - 有没有办法以编程方式在 android 中创建布局的副本?

c# - Xamarin "Aapt.exe"退出,代码为 -1073741819

c# - 对 Dictionary<int, double> 类型的 Linq 查询

c# - 从 Azure Webjob 连接到 Yammer

java - 在 Kotlin 中将 Dp 转换为 Px - 这种转换永远不会成功

android - 如何将 ContextWrapper 类与 subscribeWith 一起使用

android 的单声道不支持 OpencvSharp 版本 2.4.8.20140523(任何 CPU 构建)

c# - 使用长时间运行的构造函数设计对象

c# - 将日期时间偏移应用于美国东部时区

android - 如何处理 sencha touch 应用程序上的设备后退按钮