具有返回值的Hangfire背景作业
我正在从Task.Run切换到Hangfire 。 在.NET 4.5+中, Task.Run
可以返回Task
,它允许我运行返回void
以外的任务。 我通常可以通过访问MyReturnedTask.Result
属性来等待并获得我的任务结果
我的旧代码示例:
public void MyMainCode() { List listStr = new List(); listStr.Add("Bob"); listStr.Add("Kate"); listStr.Add("Yaz"); List<Task> listTasks = new List<Task>(); foreach(string str in listStr) { Task returnedTask = Task.Run(() => GetMyString(str)); listTasks.Add(returnedTask); } foreach(Task task in listTasks) { // using task.Result will cause the code to wait for the task if not yet finished. // Alternatively, you can use Task.WaitAll(listTasks.ToArray()) to wait for all tasks in the list to finish. MyTextBox.Text += task.Result + Environment.NewLine; } } private string GetMyString(string str) { // long execution in order to calculate the returned string return str + "_finished"; }
据我所知,从Hangfire的快速入门页面,您的主要人物是BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));
完美地将代码作为后台作业运行,但显然不支持具有返回值的作业(如上面提到的代码)。 是对的吗? 如果没有,我如何调整我的代码才能使用Hangfire?
PS我已经看过HostingEnvironment.QueueBackgroundWorkItem
( 这里 ),但它显然缺乏相同的function(后台工作必须void
)
编辑
正如@Dejan所知,我想切换到Hangfire的主要原因与.NET QueueBackgroundWorkItem
在.NET 4.5.2中添加QueueBackgroundWorkItem
原因相同。 这个原因在Scott Hanselman关于ASP.NET背景任务的伟大文章中得到了很好的描述。 所以我要引用这篇文章:
QBWI(QueueBackgroundWorkItem)调度可以在后台运行的任务,与任何请求无关。 这与普通的ThreadPool工作项不同,ASP.NET自动跟踪通过此API注册的工作项当前正在运行,并且ASP.NET运行时将尝试延迟AppDomain关闭,直到这些工作项完成执行。
一个简单的解决方案是轮询监控API,直到作业完成,如下所示:
public static Task Enqueue(Expression methodCall) { string jobId = BackgroundJob.Enqueue(methodCall); Task checkJobState = Task.Factory.StartNew(() => { while (true) { IMonitoringApi monitoringApi = JobStorage.Current.GetMonitoringApi(); JobDetailsDto jobDetails = monitoringApi.JobDetails(jobId); string currentState = jobDetails.History[0].StateName; if (currentState != "Enqueued" && currentState != "Processing") { break; } Thread.Sleep(100); // adjust to a coarse enough value for your scenario } }); return checkJobState; }
注意 :当然,在Web托管的场景中,您不能依赖于任务的继续( task.ContinueWith()
)在作业完成后做更多的事情,因为AppDomain可能会被关闭 – 出于您可能想要的相同原因首先使用Hangfire。
- 如何使用C#从asp.net的sql表中读取每行和每列中的数据?
- Membership.DeleteUser(UserName,true)不从角色中删除用户
- 共享资源锁
- 从Html.TextBoxFor获取价值
- 解码所有HTML实体
- 如何将ListItemCollection(dropdownlist.items)转换为字典?
- System.Web.Configuration.WebConfigurationManager和System.Configuration.ConfigurationManager之间的行为差异
- 如何在长服务器进程中显示信息丰富的实时进度数据
- 在ASP.NET中正确使用Response.Write()