具有返回值的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。