【问题标题】:C# Best way to keep UI responsive during heavy workloadC# 在繁重工作量期间保持 UI 响应的最佳方法
【发布时间】:2019-08-14 21:19:45
【问题描述】:

我们的网络服务器会即时生成文件以供下载。这需要大约两分钟的繁重处理,因为它需要 1000 个单词的模板,邮件合并它们,将它们转换为 pdf,然后从这 1000 个文件中压缩。该处理正在冻结网络服务器同时无法执行任何其他操作,这是一个问题,因为它为客户端托管了 23 个子域,并且他们注意到它冻结了。

如何强制 UI 线程完成一些工作?我一直在研究 Thread.Sleep 和 Thread.Yield 但也许我没有正确实现它们。我对线程的概念很陌生。

【问题讨论】:

  • 使用Async方式处理繁重的工作负载
  • Thread.Sleep 将停止线程休眠。不好。
  • 我建议改写这句话,这样更清楚,然后:The processing is freezing the web browser from being able to do anything else
  • 那就不要你的网络服务器进程文件了。它不是为了这样做。它旨在处理 HTTP 请求。在可扩展的后台处理器应用程序(可能托管为 Windows 服务或 Azure 函数等)中完成这项工作。然后,您可以根据需要启动任意数量的服务器来执行工作,同时防止 Web 服务器过载。
  • 梅森我会考虑你的建议。我对允许将这些东西带入杂草的范围有限制,而且我们没有任何天蓝色的东西,但可能我们可以将处理卸载到使用生成的控制台应用程序。

标签: c# multithreading


【解决方案1】:

在网络服务器上开始处理时,生成一个“作业 ID”并将其存储在某个地方(例如数据库)。添加一个端点,以便客户端可以查询作业的状态。处理完成后,用户可以使用作业 ID 来获取结果文件。它的工作原理是这样的:

  • 用户想要处理文件。他们调用start 端点,该端点返回一个 JobId。
  • 服务器开始在非请求线程中处理该作业,或者该作业被另一台服务器拾取并处理,该服务器专用于该任务。当线程完成时,它会相应地更新作业的状态。

稍后...

  • 用户想知道他们进程的状态。他们定期使用其 JobId 调用 status 端点。服务器回复一些状态信息以显示给用户。

稍后...

  • 一旦作业的状态更改为“完成”,用户可以使用其 JobId 调用 result 端点以获取最终文件。

繁重的处理应在非 UI、非请求线程中完成,以免影响其他用户。

使用这种方法,您甚至可以完全在另一台服务器上进行处理。 Web 服务器所做的只是允许用户创建和查询处理作业。

【讨论】:

  • 这一切都是真的,我知道这一点,但我(显然)在不同的线程上遇到了麻烦。 Parallel.For 会冻结 UI 线程吗?
  • 调用Parallel.For的线程等待Parallel.For完成。
  • 好吧,我试过了:我把函数放在异步函数中,但我遇到了和以前一样的问题:等待永远不会结束。就好像它永远不知道线程已经完成了。
  • 约翰,提出一个新问题,然后发布一些代码。当我们看不到您的代码时,我们无法告诉您您做错了什么。
  • 我目前正在听取您的建议,并尝试将整个功能卸载到另一个应用程序中。我会让你知道它的效果如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
相关资源
最近更新 更多