我想保留一个计数器,看看有多少用户在调用Web服务。网络服务几乎在一秒钟内完成。我可以在开头增加一个变量,在结尾减少但不是我想要的。
我需要在开头增加变量并在3秒后减少计数。我考虑使用缓存过期,但我会在一秒钟内有超过1000个调用,我不想在服务器或内存上加载额外的负载。另外我知道像(hangfire)这样的fire和forget方法可以工作但是在这种情况下我需要在每个请求的类中运行计时器。
此方法也必须是线程安全的。我最近使用Redis,所以如果存在这种功能,它可以成为我的解决方案。我也更喜欢它。
目前我所做的是: 在创建日期开始时向db写一条记录 之后删除超过2秒的记录 运行程序
但这会加载数据库,我无法提出一个简单的解决方案。
请问任何想法? 感谢。
编辑: 我做了以下样本。按住增量按钮,大约90.000你将得到“对象变量未设置”错误行:
Cache("x") = CInt(Cache("x").ToString) + 1
...
Imports Microsoft.VisualBasic
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Web.Hosting
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub cmdIncrement_Click(sender As Object, e As EventArgs) Handles cmdIncrement.Click
For i As Integer = 1 To 10000
If Cache("x") Is Nothing Then Cache("x") = 0
Cache("x") = CInt(Cache("x").ToString) + 1
fireit()
Next
getvalue()
End Sub
Protected Sub cmdRefresh_Click(sender As Object, e As EventArgs) Handles cmdRefresh.Click
getvalue()
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
getvalue()
End Sub
Protected Sub getvalue()
If Cache("x") Is Nothing Then Cache("x") = 0
Label1.Text = Cache("x").ToString & " - " & Now.ToString
End Sub
Protected Sub fireit()
HostingEnvironment.QueueBackgroundWorkItem(Function(token) DecrementMyVariable("aaa", token))
End Sub
Protected Shared Async Function DecrementMyVariable(text As String, token As CancellationToken) As Task(Of String)
Await Task.Delay(5000)
Dim x As Integer = CInt(HttpRuntime.Cache("x").ToString)
HttpRuntime.Cache("x") = x - 1
Return "aaa"
End Function
End Class
答案 0 :(得分:1)
您只想将每次调用服务的日期和时间存储到日志中。然后,您可以在给定的时间段内绘制此图。将详细信息保存为CSV文件,您只需在Excel中查看数据即可。
您可以将其存储到数据库中,然后查询数据库以查找最近三秒内的所有呼叫。
答案 1 :(得分:0)
在内存中执行与当前在数据库中执行的操作相同的操作。创建共享的List(Of Date)
对象。每次调用任何方法时,都会将Date.Now
添加到该列表中。然后有一个计时器,每秒触发一次,从该共享列表中删除任何超过所需的三秒阈值的项目。只要您想获得当前用户数,就可以阅读该列表的Count
属性。将SyncLock
放在您修改或访问该列表的所有位置周围,以使其成为线程安全的。