如何获取Hangfire作业中生成的数据并在控制器中展示?
解决方案:Hangfire作业数据传递到控制器的实现
Hangfire后台作业与控制器请求上下文完全隔离,无法通过方法参数直接返回数据,你参考的思路是可行的,核心是通过共享存储(如你的数据库)中转数据,再由控制器读取展示。以下是具体集成步骤:
1. 调整作业代码:确保数据可追踪
你已经在数据库中保存了Temperature数据,只需确保后续能精准查询到该作业生成的数据。可以选择两种方式:
方式一:关联Hangfire作业ID(精准匹配)
修改Run方法,获取当前作业ID并关联到Temperature实体(需先给Temperature类添加JobId字符串字段):
Imports Hangfire Public Sub Run() Implements IEngine.Run Dim oTemperature As Temperature Dim nFahrenheit As Decimal Dim nCelsius As Decimal Dim oRandom As Random Dim jobId As String = BackgroundJob.Current.Id ' 获取当前作业ID oRandom = New Random nFahrenheit = (oRandom.NextDouble * 100.0) - 20.0 nCelsius = (nFahrenheit - 32.0) * 5.0 / 9.0 oTemperature = New Temperature With { .Fahrenheit = nFahrenheit, .Celsius = nCelsius, .JobId = jobId } Me.Context.Temperatures.Add(oTemperature) Me.Context.SaveChanges() End Sub
方式二:依赖创建时间(简单直接)
如果不需要精准匹配单个作业,可直接依赖Temperature的自增ID或创建时间,无需修改现有Run方法。
2. 控制器调度作业时记录关键标识
调度作业时,Hangfire会返回作业ID,将其存储(Session/缓存/前端)以便后续查询:
Dim oJob As IBackgroundJobClient oJob = Me.HttpContext.RequestServices.GetService(GetType(IBackgroundJobClient)) ' 调度作业并获取返回的JobId Dim jobId As String = oJob.Schedule(Of IEngine)(Sub(Engine) Engine.Run(), TimeSpan.FromMinutes(1)) ' 将JobId存入Session,供后续查询使用 Me.HttpContext.Session.SetString("LatestTempJobId", jobId) ' 传递JobId到视图(可选) Return View("TempView", New With { .JobId = jobId })
3. 控制器添加数据查询接口
编写Action用于查询作业生成的温度数据,供前端调用:
' 根据作业ID查询(对应方式一) Public Function GetJobTemperature() As IActionResult Dim jobId As String = Me.HttpContext.Session.GetString("LatestTempJobId") If Not String.IsNullOrEmpty(jobId) Then Dim temp = Me.Context.Temperatures.FirstOrDefault(Function(t) t.JobId = jobId) If temp IsNot Nothing Then Return Json(New With { .Fahrenheit = temp.Fahrenheit.ToString("F2"), .Celsius = temp.Celsius.ToString("F2") }) End If End If Return NotFound() End Function ' 或查询最新温度数据(对应方式二) Public Function GetLatestTemperature() As IActionResult Dim latestTemp = Me.Context.Temperatures.OrderByDescending(Function(t) t.Id).FirstOrDefault() If latestTemp IsNot Nothing Then Return Json(New With { .Fahrenheit = latestTemp.Fahrenheit.ToString("F2"), .Celsius = latestTemp.Celsius.ToString("F2") }) End If Return NotFound() End Function
4. 前端页面轮询展示数据
在页面中通过JavaScript定时调用查询接口,更新温度展示:
<div class="temperature-display"> <p>当前温度:<span id="fahrenheit"></span> °F / <span id="celsius"></span> °C</p> </div> <script> // 每10秒查询一次数据 setInterval(() => { fetch('/YourControllerName/GetLatestTemperature') .then(res => res.json()) .then(data => { document.getElementById('fahrenheit').textContent = data.Fahrenheit; document.getElementById('celsius').textContent = data.Celsius; }) .catch(err => console.error('查询温度失败:', err)); }, 10000); </script>
为什么直接传DTO无效?
Hangfire作业运行在独立的后台进程中,与控制器的HTTP请求上下文完全分离。方法参数仅用于向作业传递输入数据,无法实现从作业向控制器的反向数据传递,必须通过数据库、缓存等共享存储中转。
内容的提问来源于stack exchange,提问作者InteXX
相关产品推荐
相关产品推荐

