如何使用async/await实现命令模式 [英] How to implement Command Pattern with async/await

查看:79
本文介绍了如何使用async/await实现命令模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在升级一些通用代码,以供Windows Universal使用,并且正在努力转换命令模式以与新的异步/等待功能一起使用.

i'm currently upgrading some existing code for use by windows universal and am struggling to convert a command pattern to work with the new async/await functionality.

我有一个命令调度程序类,该类在其自己的线程中运行并处理已添加到其队列中的命令.有问题的方法如下:

I have a command scheduler class that runs within its own thread and processes commands that have been added to its queue. The method in question looks like this:

private List<ICommandItem> _items;

private void ProcessCommands()
{
    while(_items.count > 0)
    {
        _items[0].Execute();
        _items.RemoveAt(0);
    }
}

我的问题是我的某些ICommandItem.Execute()方法现在需要异步,因为它们涉及文件io,而其他方法则没有异步方法.我该如何修改上述模式,以便:

My problem is that some of my ICommandItem.Execute() methods now need to be async because they involve file io whilst others have no async methods. How could I modify the above pattern so that:

  1. 我的执行程序可以处理异步和非异步ICommandItems
  2. 执行程序仅在上一个命令完成后才开始执行命令.

我很乐意仅同步执行这些方法,但是现在到处都会导致死锁.

I would be happy to just execute the methods synchronously but that now causes deadlocks everywhere.

推荐答案

我的问题是我的某些ICommandItem.Execute()方法现在需要异步,因为它们涉及文件io,而其他方法则没有异步方法.

My problem is that some of my ICommandItem.Execute() methods now need to be async because they involve file io whilst others have no async methods.

从技术上讲,异步(返回<任务> > )签名仅意味着实现可能是异步的.因此,虽然可以引入一个单独的异步接口,但是另一种方法是将现有接口更改为 Task -returning:

Technically, an asynchronous (Task-returning) signature only means that the implementation may be asynchronous. So, while you can introduce a separate asynchronous interface, another approach is to change the existing interface to be Task-returning:

interface ICommandItem
{
  Task ExecuteAsync(); // Used to be "void Execute();"
}

您的同步实现将不得不更改以返回 Task :

Your synchronous implementations will have to change to return a Task:

Task ICommandItem.ExecuteAsync()
{
  // Do synchronous work.
  return Task.CompletedTask; // If you're not on 4.6 yet, you can use "Task.FromResult(0)"
}

虽然异步实现很简单:

async Task ICommandItem.ExecuteAsync()
{
  await ...; // Do asynchronous work.
}

您的跑步者"可以只使用 await :

And your "runner" can just use await:

private async Task ProcessCommandsAsync()
{
  while(_items.count > 0)
  {
    await _items[0].ExecuteAsync();
    _items.RemoveAt(0);
  }
}

这篇关于如何使用async/await实现命令模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆