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

时间:2015-09-28 02:42:37

标签: c# asynchronous serial-port win-universal-app

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

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

但是,VS2015创建的通用应用程序包含大量生成的非异步代码,这些代码无法理解。我想有一个普遍的模式可以处理这个问题,但我找不到它的任何痕迹。那我该怎么办?

4 个答案:

答案 0 :(得分:4)

  

我想在某个地方有一个普遍的模式可以处理这个问题,但我找不到它的任何痕迹。那我该怎么办?

我的推荐总是这样:

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

    async“通过代码库增长”时,您可能会遇到各种问题 - 例如,您无法在属性获取器或构造函数中使用await。我有series of posts on my blog describing techniques to work around these problems

答案 1 :(得分:0)

通用应用并没有被&#34; 这个应用程序异步&#34;和&#34; 这个应用程序不是异步的&#34;,创建async方法意味着您必须彻底更改所有内容才能使用它们。

asyncawait的一个好处是,您可以在不冻结UI的情况下执行长时间运行的操作。

Stephen Cleary&#34; 所有事情的同步模式&#34;是完全没必要的,它滥用了异步方法的目的。

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

重要的是,您不要在创建数百万async方法的不寻常模式中消耗,找出需要异步并实现此方法相应的功能。

部分UWP API async的原因是因为某些进程不是即时的,您必须记住,在调用async API方法时,您要求操作系统代表您执行操作。事实是,操作系统可能不是就绪,或者可能过载并且可能无法立即提供您的请求,因此这些方法是异步的,这可以确保您的应用程序不会挂起请求。

我建议您阅读here

答案 2 :(得分:0)

这是新手混淆的结果。

一个。术语“异步功能”有三个含义:

A.1。签名中具有“异步”术语的函数。这个术语的唯一意义是编译器不会将函数体中的“await”视为变量,但它会将其视为await语句。它不会以任何其他方式更改签名,它严格来说是为了向后兼容。

A.2。类型任务的功能可以等待。

A.3。类型为Task的函数,在正文中也有await语句。

B中。 await语句不会阻止UI处理:如果来自UI基础结构的一个回调正在等待await语句,则仍会执行UI消息处理。

因此,为了从UI方法调用异步函数(A.2):

(a)向UI功能签名(A.1)添加“异步”术语。

(b)在此函数中使用await语句来调用异步库函数(A.2)

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

答案 3 :(得分:0)

async-await模式产生的最大混乱是模式只是将一个函数包装在一个Task中,运行它并返回正在运行的Task(这一点非常重要,因为你没有&#39;总是希望你的任务自动启动......)。

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

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

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

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