c#将通用Windows应用程序转换为异步

本文关键字:程序转换 异步 应用 Windows | 更新日期: 2023-09-27 18:14:42

我是windows的新手,我正在使用通用应用程序制作一个爱好项目。几天后,我发现连接串行端口的唯一方法是使用来自和相关的SerialDevice类的异步方法。

我喜欢关于这个主题的一般建议:一旦你使用一个串行api,将整个应用程序转换为异步从'Main' (http://blog.stephencleary.com/2012/02/async-and-await.html)开始要比处理与同步调用异步方法相关的问题容易得多。

然而,由VS2015创建的通用应用程序包含大量生成的非异步代码,这些代码不是为了让人理解而生成的。我想在某个地方有一个通用的模式来处理这个问题,但我找不到任何痕迹。那我该怎么办呢?

c#将通用Windows应用程序转换为异步

我想在某个地方有一个通用的模式来处理这个问题,但我找不到任何痕迹。那我该怎么办呢?

我的建议总是这样的:

  1. 从"叶子"开始,识别自然异步操作。在您的情况下,这很容易,因为在Windows通用平台中,自然异步操作只有具有异步api。
  2. 使用await调用异步api。
  3. await的存在将要求调用方法为async(并且您应该将其返回类型从void更改为Task或从T更改为Task<T>)。
  4. 这个转换使调用方法异步,所以回到步骤(2),对于,它是调用者。
  5. 重复直到你找到一个"root"方法——在Windows Universal应用程序中,这通常是一个事件处理程序,必须是async void(不允许是async Task)。

async在你的代码库中"增长"时,你可能会遇到各种各样的问题——例如,你不能在属性getter或构造函数中使用await。我的博客上有一系列的文章描述了解决这些问题的技术。

通用应用程序不会被"这个应用程序是异步的"answers"这个应用程序不是异步的"分开,创建async方法不是意味着你必须改变一切才能使用它们。

asyncawait的优点之一是允许您在不冻结UI的情况下执行长时间运行的操作。

Stephen Cleary的"async所有的"模式是完全没有必要的,它滥用了异步方法的目的。

大多数代码不需要封装在异步方法中,同步方法几乎可以很好地处理所有事情。然而,对于长时间运行的进程,例如从web服务请求数据,最适合使用异步方法,因为它需要很长时间。

重要的是,您不要被创建数百万个async方法的不寻常模式所消耗,弄清楚需要异步并相应地实现此功能。

一些UWP API是async的原因是因为一些进程不是瞬时的,你必须记住,当调用async API方法时,你正在要求操作系统代表你执行操作。事实是,操作系统可能没有准备好,或者可能过载,可能无法立即为您的请求提供服务,因此这些方法是异步的,这确保您的应用程序不会挂起请求。

我建议在这里阅读这方面的内容。

这是新手混淆的结果。

。术语"异步函数"有三个含义:

.。在签名中包含'async'项的函数。这个术语的唯一意义是编译器不会将函数体中的'await'视为变量,而是将其视为await语句。它不会以任何其他方式改变签名,并且这里严格是为了向后兼容。

a。可等待任务类型的函数。

出具。Task类型的函数体中也有await语句

B。UI处理不会被await语句阻塞:如果UI基础架构的一个回调正在等待await语句,UI消息处理仍然会执行。

所以为了从UI方法调用async函数(A.2):

(a)在UI函数签名(a .1)中增加'async'术语。

(b)在函数内部使用await语句调用异步库函数(A.2)

(c)以某种方式处理异步执行的结果

从async-await模式中产生的最大困惑是,该模式所做的只是将函数包装在Task中,运行它并返回正在运行的Task(理解这一点非常重要,因为您并不总是希望您的Task自动启动…).

一旦你意识到这一点,就不难理解任何异步调用都可以很容易地被Task这样包装起来。

    public void PersistChanges()
    {
        var saveTask = new Task(() => PersistChangesAsync());
        saveTask.Start();
    }

当然,正如在其他地方提到的,你会想要确保你运行异步调用尽可能多的异步,所以,例如,如果你有一个保存按钮在你的应用程序中,你有该事件异步拾取,然后调用异步PersistChangesAsync。

但是在我的应用程序启动时,我可能不想在基本设置加载之前发生任何事情,用户已经被验证或其他什么,然后你甚至可以使用savetask . runsynchronous()(尽管显然你仍然可以异步运行几个子任务,然后等待结果(如果有的话,或者在一切完成时定义一个延续任务)