如何在asp.net mvc中停止当前工作并开始新工作使用quartz.net?

时间:2018-01-21 13:31:58

标签: asp.net-mvc quartz.net

我在一个网站上创建了一个爬虫,它必须阅读一个网站并从它的网站上获取一些值。我已经使用了quartz.net和Asp.net MVC。但是我的问题是什么?事实上,我的问题是,例如,他/她第一次开始刮取"Stackoverflow.com"大约5个小时然后他/她决定停止"stackoverflow.com"并开始废弃新网站。所以,我该怎么办?

enter image description here

   [HttpPost]
    public ActionResult Index(string keyword, string url)
    {
        IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();

        scheduler.Start();
        IJobDetail job = JobBuilder.Create<ScrapJob>()
            .WithIdentity("MyScrapJob")
            .UsingJobData("url", url)
            .UsingJobData("keyword", keyword)
            .Build();

        ITrigger trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(
            s => s.WithIntervalInSeconds(20).OnEveryDay().StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
            ).Build();
        scheduler.ScheduleJob(job, trigger);

        return View(db.Scraps.ToList());
    }
 public List<ScrapJob> Scraping(string url, string keyword)
    {
        int count = 0;
        List<ScrapJob> scraps = new List<ScrapJob>();
        ScrapJob scrap = null;
        HtmlDocument doc = new HtmlDocument();
        try
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";

            using (var response = (HttpWebResponse)request.GetResponse())
            {

                using (var stream = response.GetResponseStream())
                {
                    doc.Load(stream, Encoding.GetEncoding("UTF-8"));
                    foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//text()"))
                    {
                        if (node.InnerText.ToString().Contains(keyword))
                        {
                            count++;
                            scrap = new ScrapJob { Keyword = keyword, DateTime = System.DateTime.Now.ToString(), Count = count, Url = url };
                        }

                    }

                }
            }
        }
        catch (WebException ex)
        {
            Console.WriteLine(ex.Message);
        }
        //  scraps.Add(scrap);
        var isExist = db.Scraps.Where(s => s.Keyword == keyword && s.Count == scrap.Count).Max(s => (int?)s.Id) ?? 0;
        if (isExist == 0)
        {
            db.Scraps.Add(scrap);
            db.SaveChanges();
        }



        return scraps;
    }

    public void Execute(IJobExecutionContext context)
    {
        //ScrapJob scraps = null;
        using (var scrap = new ScrapJob())
        {
            JobKey key = context.JobDetail.Key;
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            string url = dataMap.GetString("url");
            string keyword = dataMap.GetString("keyword");
            scrap.Scraping(url, keyword);
        }
    }

1 个答案:

答案 0 :(得分:1)

我不确定你为什么选择QUARTZ,但我认为这些东西会对你有所帮助。

这是一个以唯一标识符

中断和删除作业的代码示例
public void DeleteJob(JobKey jobKey)
{
    var scheduler = StdSchedulerFactory.GetDefaultScheduler();

    var executingJobs = scheduler.GetCurrentlyExecutingJobs();

    if (executingJobs.Any(x => x.JobDetail.Key.Equals(jobKey)))
    {
        scheduler.Interrupt(jobKey);
    }

    scheduler.DeleteJob(jobKey);
}

但我相信你需要定义你期望的行为,因为例如它可能会更复杂一些:

  1. 如果您想暂停工作并在完成其他网站后恢复工作/坚持一些状态和进度/或只记录进度
  2. 如果您希望它们并行运行并同时处理多个站点。 (你只需要给出不同的名字而不是硬编码的.WithIdentity(&#34; MyScrapJob&#34;))
  3. 使用scheduler.GetCurrentlyExecutingJobs(),您可以获取当前正在执行的作业,向用户显示这些作业并让他决定要做什么。
  4. 另外,在查看您的操作方法时,我不确定这是否是您对该触发器的预期行为。令我困扰的是db.Scraps.ToList()你将实现整个表,你可以考虑在你的情况下添加分页是没有必要的,因为你只会显示计数,但如果你在网格中有很多记录它是强制性的

    关于刮削方法 而不是

    var isExist = db.Scraps.Where(s => s.Keyword == keyword && s.Count == scrap.Count).Max(s => (int?)s.Id) ?? 0;
    

    你可以使用.Any

    var exists = db.Scraps.Any(s => s.Keyword == keyword && s.Count == scrap.Count);
    

    这将返回布尔值,您可以检查是否(!exists)

    您可以查看https://github.com/AngleSharp/AngleSharp高性能网络解析库。超级好用。

    如果按关键字和计数检查,我发现按关键字重复记录的可能性 - 不确定您是否想要这个或只是想用它的计数器更新现有记录

    祝你好运!我希望这个答案可以帮助你:)