c# - 如何有效地限制 MVC Web 应用程序中从控制器到前端的 SignalR 集线器消息的速率?
问题描述
我的 Web 应用程序的前端有一个进度条,它通过侦听从后端的 SignalR 集线器发送的消息来获取其当前百分比。它跟踪一个长期运行的过程,该过程具有多个阶段和多次迭代。
我最初的设置是每次迭代都简单地发送一条消息。然而,这导致了一些问题,因为前端的迭代速率(以及消息速率)太快了,并且条变得非常跳跃和错误。
因此,我决定按以下方式使用 Stopwatch 对象(SendProgress()
告诉集线器向客户端发送消息的过程在哪里):
int progressCount = 1;
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for(int i=0; i<taskCount; i++)
{
//PROCESS DONE HERE
if (stopWatch.Elapsed.TotalMilliseconds >= 500.0)
{
SendProgress(taskCount, progressCount, 0, 40);
stopWatch.Reset();
stopWatch.Start();
}
progressCount++;
}
从而防止消息的发送速度超过每 500 毫秒一次。
这在限制消息速率方面效果很好,但是我注意到性能下降,经过一些研究,我收集到这是由于使用了低效的秒表。
这里有什么更好的方法?我也想过使用Thread.Sleep()
,但这只会给算法增加人为的缓慢,这显然很糟糕。有没有办法可以准确地控制消息速率,而不会太慢?
解决方案
在控制台应用程序中运行它以查看逻辑是否适用于您想要执行的操作。检查评论以跟踪正在发生的事情(如果您需要我进一步分解,请告诉我)。快乐编码!;)
static void Main(string[] args)
{
//set the percentage you want to show progress for (eg, every 20%).
const int updatePercentage = 20;
//this is just the total of the for loop for this example.
const int loopMax = 1000000;
//calculate what 20% of the total is, to set as the check point used to show the progress.
decimal loopCheck = Convert.ToDecimal(loopMax * (Convert.ToDecimal(updatePercentage) / 100));
for (int i = 1; i <= loopMax; i++)
{
//check if the mod of the current position meets the check point.
if ((i % loopCheck) == 0)
{
//show the progress...
Console.WriteLine($"You've reached the next {updatePercentage}% of the for loop ({i.ToString("#,##0")})");
}
}
Console.ReadLine();
}
推荐阅读
- amazon-web-services - Terraform v0.12 不再支持 .tfvars 文件中的块
- python - Pytesseract:为什么 pytesseract 无法识别带有 cv2.adaptiveThreshold 的字母?
- tcp - 如果数据刚刚被 VPN 软件加密,我的互联网服务提供商如何知道 VPN 服务器的位置?
- python - Django:QuerySet.update() 在使用带有过滤器的 Count() 时返回 FieldError
- python - 根据日期对 csv 文件进行排序的代码有什么问题?
- nativescript - Nativescript 中的 http2 客户端支持有哪些选项?
- django - 意外结果:“详细信息”:“方法 \"GET\" 不允许。”
- excel - VBA Excel,更快的复制粘贴公式代码
- tensorflow - 不仅在跟踪时如何在 TensorFlow 中读取文件?
- twitter - 用于查找 Twitter 数据的软件包