草庐IT

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

coder 2023-12-05 原文

目前我正在将现有的 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 下的不良做法?的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  7. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  8. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

  9. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  10. ruby - Watir ... sleep 和等待之间的区别 - 2

    有什么显着的区别吗sleep10和wait_until(10)他们似乎都在做同样的事情:WAITING10秒,然后继续下一步 最佳答案 sleep在指定时间内什么都不做。wait_untiltakesablock.它一直等到block评估为真或超时。如果没有给出block,它们的行为相同。 关于ruby-Watir...sleep和等待之间的区别,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que

随机推荐