【问题标题】:How can i call an async action method using Hangfire如何使用 Hangfire 调用异步操作方法
【发布时间】:2015-09-10 15:36:12
【问题描述】:

我正在开发一个 asp.net mvc5 Web 应用程序,并且我安装了 Hangfire:-

Install-Package Hangfire

之后我创建了一个 startup.css 类如下:-

public class Startup
{
   public void Configuration(IAppBuilder app)
   {

   }
}

然后在我的 global.asax 文件中,我尝试调用 2 个操作方法; Index () & ScanServer(),如下:-

 HomeController h = new HomeController();
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);


            RecurringJob.AddOrUpdate(() =>  h.Index(), Cron.Minutely);
        }

&

 RecurringJob.AddOrUpdate(() =>  h.ScanServer(*****), Cron.Minutely);

现在当 Hangfire 尝试调用具有以下定义的 Index() 操作方法时:-

 public ActionResult Index()

我收到了这个错误:-

JobStorage.Current 属性值尚未初始化。你必须 在使用 Hangfire 客户端或服务器 API 之前设置它。

当 Hangfire 尝试调用 ScanServer() 操作方法时,它是一个异步任务,具有以下定义:-

 public async Task<ActionResult> ScanServer(string tokenfrom)

我收到了这个错误:-

不支持异步方法。请先使它们同步 在后台使用它们。

那么任何人都可以建议如何解决这两个问题吗?

谢谢

编辑

我在 Startup 类中写了以下内容:-

using Hangfire;
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ScanningFinal;
[assembly: OwinStartup(typeof(Startup))]
namespace ScanningFinal
{

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration
           .UseSqlServerStorage("scanservice");
        }
    }
}

& 这里是连接字符串:-

 <add name="scanservice"    connectionString="data source=localhost;initial catalog=ScanningService;integrated security=True" providerName="System.Data.SqlClient"/>

但我仍然收到此错误:-

JobStorage.Current 属性值尚未初始化。你必须 在使用 Hangfire 客户端或服务器 API 之前设置它。

【问题讨论】:

  • Startup类中的配置方法是否留空?
  • Hangfire 必须有一个数据库来存储作业。确保您阅读了the documentation。看看它怎么说.UseSqlServer?您需要这样做,或者使用其文档中列出的其他作业存储数据库之一,例如 Redis 或 MongoDB。
  • @mason 但我可以强制它将作业存储在文本文件中吗?或者它需要是一个数据库?
  • @Tom 是的,我把它们留空了,但如果我想访问仪表板,我需要它们?这是否也会导致调用异步操作方法的问题?
  • Hangfire 怎么知道是它创造了它们还是其他东西创造了它们?它不会。因此,如果您有为其设置数据库的脚本,那就去吧。

标签: c# asp.net asynchronous asp.net-mvc-5 hangfire


【解决方案1】:

您需要在配置方法中配置 Hangfire。

[assembly: OwinStartup(typeof(YourApp.Startup))] // Change YourApp to your base namespace
public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseHangfire(config => 
        {
            config.UseSqlServerStorage("NameOfConnectionStringKey"); // Other storage options are available
            config.UseDashboardPath("/hangfire");
            config.UseServer();
        });
    }
}

基本上,您的第一个问题是您尚未将 Hangfire 配置为使用数据库。通过上述解决方案,我告诉hangfire 使用SqlServer 作为作业存储,将web.config 中定义的connectionString 键传递给它。如果您不想使用 SQL Server,那么您可以使用其他存储选项 - 我在项目中使用 MongoDB 取得了成功。

我还将设置仪表板的路径,以便您可以在浏览器中访问漂亮的 UI。

你也可以在这里提供你选择的依赖注入。

关于您的第二个问题,您能否将服务方法从异步更改为同步方法?

【讨论】:

  • 是的,我可以将我的服务从异步更改为同步,但我不想这样做?因为我希望操作方法是异步操作方法...
  • 我几乎肯定 Hangfire 无论如何都会异步运行操作,所以我不会太担心。
  • 但我需要将操作方法​​设置为异步,因为最终用户可以手动调用相同的操作方法..所以在这种情况下,我需要创建另一个版本的操作方法..不会很可靠......我的意思是我最终会有两个版本的操作方法异步和同步!你能推荐一下吗?
  • @johnG 为什么需要另一种操作方法?为什么不使用调用Task的Wait方法的方法呢?
  • @mason 你能在这方面提供更多建议吗?不知道我明白你的意思吗?现在我需要异步操作,因为用户可以从他们的浏览器手动调用异步方法,而 hangfire 不允许调用异步操作方法,您能否就您的建议提出更多建议?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2015-08-20
  • 2017-04-25
  • 2016-04-07
  • 2017-03-12
  • 1970-01-01
相关资源
最近更新 更多