使用CacheItemRemovedCallback模拟Windows服务在首次运行时的行为不同

时间:2014-12-11 09:03:21

标签: c# asp.net

我使用CacheItemRemovedCallback模拟了一个基于此源的Windows服务:

Simulate a Windows Service using ASP.NET to run scheduled jobs

除了应用程序回收或重新启动后的第一次运行之外,一切都运行良好。

的Global.asax.cs

protected void Application_Start(object sender, EventArgs e)
{
    RegisterCacheEntry();
}

private bool RegisterCacheEntry()
{
    if (null != HttpContext.Current.Cache[DummyCacheItemKey]) return false;

    int interval = Properties.Settings.Default.SchedulerInterval;

    HttpContext.Current.Cache.Add(
        DummyCacheItemKey, "StartingScheduler", null,
        Cache.NoAbsoluteExpiration, TimeSpan.FromHours(interval),
        CacheItemPriority.NotRemovable,
        new CacheItemRemovedCallback(CacheItemRemovedCallback)
    );

    return true;
}

public void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
{
    Scheduler.HitPage(Properties.Settings.Default.Dummy);
    string dirScheduler = Properties.Settings.Default.Scheduler;
    Scheduler.Manage(dirScheduler);
}

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.Request.Url.ToString() == Properties.Settings.Default.Dummy)
    {
        RegisterCacheEntry();
    }
}

公共静态类调度程序

public static string _DirScheduler { get; set; }

public static void Manage(string dirScheduler)
{
    _DirScheduler = dirScheduler;
    string[] schedulesCfg = Directory.GetFiles(dirScheduler, "*.xml");

    foreach (string scheduleCfg in schedulesCfg)
    {
        //scheduleData = Class to store the schedule data
        ThreadPool.QueueUserWorkItem(o => FireAway(scheduleData));
    }
}

private static void FireAway(Schedule schedule)
{
    string month = DateTime.Now.Month.ToString();

    if (month.Length == 1)
    {
        month = month.Insert(0, "0");
    }

    // Wait Handle to Manage Access to Log File
    EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "LogFile_Shared");

    // Lock the log file
    waitHandle.WaitOne();
    WriteLog("path_to_log_file", schedule, "started");
    // Release the lock on log file
    waitHandle.Set();

    // Ok until here !
    string message = ScheduleScript.Launch(schedule);

    // Code not executed from here (only after application end or recycle)
    if (schedule.Repeat == "0")
    {
        waitHandle.WaitOne();
        UpdateScheduler(schedule);
        waitHandle.Set();
    }

    // Lock the log file
    waitHandle.WaitOne();
    WriteLog("path_to_log_file", schedule, message);
    // Release the lock on log file
    waitHandle.Set();
}

private static void UpdateScheduler(Schedule schedule)
{
    // Update a xml file containing scheduler data
}

公共静态类ScheduleScript

public static string Launch(Schedule schedule)
{
    string message = "finished";
    string messageScheduler = string.Empty;

    using (WebClientCustom web = new WebClientCustom(10800000)) // 3 hours timeout
    {
        try
        {
            string res = web.DownloadString(schedule.Script);
        }
        catch (Exception e)
        {
            message = e.Message;
        }
    }
    return message;
}

在静态类Scheduler中,所有内容都会执行到ScheduleScript.Launch(schedule)。然后,代码不会执行(日志不会更新,状态已完成,并且调度程序xml未使用UpdateScheduler方法更新)。

我尝试了一切,但没有成功。只有在应用程序被回收后才开始计划,才会出现这种情况。

例如,如果我的计划预计在上午10点启动并且尚未执行,并且我发布了新版本的应用程序或在计划的同一小时(上午10点)手动执行应用程序池回收,则会发生此行为

0 个答案:

没有答案