【发布时间】:2015-05-16 13:08:49
【问题描述】:
我正在从 Task.Run 切换到 Hangfire。在 .NET 4.5+ 中,Task.Run 可以返回 Task<TResult>,这允许我运行返回 void 以外的任务。我通常可以通过访问属性MyReturnedTask.Result 来等待并获得我的任务结果
我的旧代码示例:
public void MyMainCode()
{
List<string> listStr = new List<string>();
listStr.Add("Bob");
listStr.Add("Kate");
listStr.Add("Yaz");
List<Task<string>> listTasks = new List<Task<string>>();
foreach(string str in listStr)
{
Task<string> returnedTask = Task.Run(() => GetMyString(str));
listTasks.Add(returnedTask);
}
foreach(Task<string> 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 的 Quick Start 页面上看到的,你的主要人物是 BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));
完美地将代码作为后台作业运行,但显然不支持具有返回值的作业(如我上面介绍的代码)。那正确吗?如果没有,我该如何调整我的代码以使用 Hangfire?
附:我已经看过HostingEnvironment.QueueBackgroundWorkItem (here) 但它显然缺少相同的功能(后台作业必须是void)
编辑
正如@Dejan 发现的那样,我想切换到 Hangfire 的主要原因与 .NET 人员在 .NET 4.5.2 中添加 QueueBackgroundWorkItem 的原因相同。这个原因在 Scott Hanselman 关于 ASP.NET 中的后台任务的精彩 article 中得到了很好的描述。所以我要引用这篇文章:
QBWI (QueueBackgroundWorkItem) 调度一个可以在后台运行的任务,独立于 任何请求。这与普通的 ThreadPool 工作项的不同之处在于 ASP.NET 自动跟踪注册了多少工作项 通过此 API 当前正在运行,并且 ASP.NET 运行时将 尝试延迟 AppDomain 关闭,直到这些工作项目完成 正在执行。
【问题讨论】:
-
方法的返回值显示在控制面板的作业信息页面上。如果您查看 Hangfire 作业的相关数据库表,则返回值应存储在其中的一个字段中。请参阅github.com/HangfireIO/Hangfire/pull/161 - 除此之外,我不确定是否可以通过编程方式访问它
-
我有完全相同的问题。在此期间你有什么想法吗?
-
还没有。您可以随时阅读 Scott Hanselman 关于 ASP.NET 中的后台任务的精彩文章:hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx 我可能很快就会开始赏金,也许我们会得到答案。
-
请注意,如果您对此感兴趣,Hangfire 1.4.0 引入了continuation 的概念。
-
您是否使用 Hangfire 来处理您的应用程序中的多线程?如果是这样,您可能使用了错误的工具。
标签: c# asp.net asynchronous hangfire