【问题标题】:Await and fire-and-forget in .NET Core.NET Core 中的等待和即发即弃
【发布时间】:2020-07-27 12:34:29
【问题描述】:

我正在开发 Blazor 应用程序。
当用户填写表单时,需要将数据保存到表格中,并且需要运行更长的任务。
用户不需要等待这个更长的任务完成。稍后会通知他。
但是当长任务完成时,需要更新表条目。
如何做到这一点?

这是我当前的代码,它会阻止用户直到所有操作完成:

        public async Task<Client> Create(Client client)
        {
            client.DatabaseCreated = false;

            await _context.Clients.AddAsync(client);
            await _context.SaveChangesAsync();
            Debug.WriteLine("Client added");

            // Run longer task.
            try
            {
                // TODO: Don't wait for it:
                var longTask= myLongTask(client.Code, client.Id);
                // update table entry
                client.DatabaseCreated = true;
                var updateClient = _context.SaveChangesAsync();
                await Task.WhenAll(longTask, updateClient);
                Debug.WriteLine("Client updated");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            Debug.WriteLine("Client returned");
            return client;
        }

【问题讨论】:

标签: c# asp.net-core async-await fire-and-forget


【解决方案1】:

用户不需要等待这个更长的任务完成。稍后会通知他。 如何做到这一点?

要以可靠的方式执行此操作,您需要 1) 具有可靠的队列(例如,Azure 队列 / Amazon SQS 等),以及 2) 具有后台服务(例如,ASP.NET Core 后台服务/ Azure 函数 / Amazon Lambda / 等)。 ASP.NET API 只会将消息放入队列然后返回;后台服务从队列中读取并处理消息。

【讨论】:

  • 感谢您的回复,并为您的困惑感到抱歉。我知道以后如何通知用户,那部分已经在工作了。我需要知道如何在不让用户等待的情况下运行长任务并更新数据库。在其他 cmets 中,人们建议使用 Task.Run 并手动创建 dbContext。我先试试看。
  • @PaulMeems:Task.Run 方法的问题在于(a)当您“尝试”时它会起作用,但(b)它偶尔会在生产中静默失败(例如,如果应用程序池在不方便的时候被回收)。如果这对你来说可以接受,那就去做吧,如果不是,你需要一个更可靠的解决方案。
  • 阅读所有 cmets 和相关帖子的链接我改变了主意。由于我稍后还需要创建 WebJobs,因此我将创建一个 webjob 来执行我的长时间运行的任务。这很可能会引发新的问题,例如如何将 DI 与 Web 作业的静态入口点一起使用。如果我遇到困难,我会将它们作为新问题发布。感谢您的见解。
  • 当您横向扩展发布者和消费者时,这不仅可靠而且速度更快。我也遇到了同样的情况,通过bus解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 1970-01-01
相关资源
最近更新 更多