c# - 如何序列化异步/等待?

标签 c# asynchronous async-await

假设我有这个简单的片段:

async void button_Click(object sender, RoutedEventArgs e)
{
    await Task.Factory.StartNew(() =>
    {
        Console.WriteLine("start");
        Thread.Sleep(5000);
        Console.WriteLine("end");
    });
}

显然,每次我按下该按钮时,都会启动一个新任务,即使之前的任务仍在运行。我如何将任何新任务推迟到所有以前的任务完成之前?

更多细节:

在上面的示例中,每个新任务都与之前的任务相同。然而,在原始上下文中,任务的顺序很重要:参数可能会改变(我可以使用 DateTime.Now.Ticks 来“模拟”它)。 任务应该按照它们“注册”的顺序执行。具体来说,我的程序将与串行设备通信。我之前使用 BlockingCollection 在后台线程中完成过此操作。然而,这次有一个严格的请求/响应协议(protocol),如果可能的话,我想使用异步/等待。

可能的解决方案:

我可以想象创建任务并将它们存储在列表中。但是我将如何根据要求执行任务呢?还是应该回到之前使用的基于线程的解决方案?

最佳答案

我建议使用 SemaphoreSlim 进行同步。但是,您想 avoid Task.Factory.StartNew (正如我在我的博客上解释的那样),还有 definitely avoid async void (正如我在 MSDN 文章中解释的那样)。

private SemaphoreSlim _mutex = new SemaphoreSlim(1);
async void button_Click(object sender, RoutedEventArgs e)
{
  await Task.Run(async () =>
  {
    await _mutex.WaitAsync();
    try
    {
      Console.WriteLine("start");
      Thread.Sleep(5000);
      Console.WriteLine("end");
    }
    finally
    {
      _mutex.Release();
    }
  });
}

关于c# - 如何序列化异步/等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21163136/

相关文章:

c# - 使用 LINQ 在组内排序

c# - 如何创建通用类型类的新实例

javascript - 如何中止(停止)循环执行的 promise 链? - JavaScript

python-3.x - 在 python 中等待非异步函数

c# - 反射、属性和属性选择

c# - 如何修复此 Base 64 数组问题

c# - 异步/等待调用不返回。强制同步确实

rust - 是否可以为异步函数创建类型别名?

javascript - Nodejs 异步编程 - 为什么需要 "async"模块?什么是 "Callback Hell"/"Pyramid of Doom"?

python - 同时处理 2 个 websocket 连接的最佳方法